!! Copyright (C) Stichting Deltares, 2005-2020. !! !! 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_WBAL_ANALYSE USE WINTERACTER USE RESOURCE USE MOD_PREF_PAR, ONLY : PREFVAL USE MOD_MANAGER_UTL USE MOD_COLOURS, ONLY : ICOLOR,COLOUR_RANDOM USE IMODVAR, ONLY : DP_KIND,SP_KIND,IDIAGERROR,TP,ICPL USE MOD_IDF, ONLY : IDFALLOCATEX,IDFALLOCATESXY,IDFNULLIFY,IDFDEALLOCATEX,IDFFILLSXSY,IDFREADFREE,IDFWRITE,IDFCOPY USE MOD_WBAL_PAR USE MOD_WBAL_GRAPHICS, ONLY : DRAWBAL USE MOD_WBAL_UTL, ONLY : WBAL_ANALYSE_SAVECONFIG,WBAL_ANALYSE_READCONFIG USE MOD_UTL, ONLY : UTL_GETUNIT,UTL_CAP,UTL_IDATETOJDATE,UTL_JDATETOIDATE,ITOS,IDATETOGDATE,UTL_GDATE,UTL_GETUNIQUE_CHAR,UTL_EQUALNAMES, & UTL_WSELECTFILE,RTOS,UTL_DEBUGLEVEL,UTL_GETUNIQUE_INT,UTL_MESSAGEHANDLE,UTL_READINITFILE,UTL_SUBST,UTL_COUNT_COLUMNS USE MOD_OSD, ONLY : OSD_OPEN USE MOD_GRAPH, ONLY : GRAPH,GRAPH_DEALLOCATE,GRAPH_ALLOCATE,GRAPH_MAIN,GRAPH_INIT,GRAPHDIM USE MOD_MAIN_UTL CONTAINS !###====================================================================== SUBROUTINE WBAL_ANALYSE_MAIN(ITYPE,MESSAGE) !###====================================================================== IMPLICIT NONE INTEGER,INTENT(IN) :: ITYPE TYPE(WIN_MESSAGE),INTENT(IN) :: MESSAGE CALL WDIALOGSELECT(MESSAGE%WIN) SELECT CASE (ITYPE) CASE (PUSHBUTTON) SELECT CASE (MESSAGE%VALUE1) CASE (IDCANCEL) CALL WBAL_ANALYSE_CLOSE() CASE (IDHELP) !## save configuration CASE (IDSAVE) IF(WBAL_ANALYSE_SAVECONFIG(''))THEN; ENDIF END SELECT CASE (FIELDCHANGED) SELECT CASE (MESSAGE%VALUE1) END SELECT SELECT CASE (MESSAGE%VALUE2) END SELECT END SELECT END SUBROUTINE WBAL_ANALYSE_MAIN !###====================================================================== SUBROUTINE WBAL_ANALYSE_TAB1(ITYPE,MESSAGE) !###====================================================================== IMPLICIT NONE INTEGER,INTENT(IN) :: ITYPE TYPE(WIN_MESSAGE),INTENT(IN) :: MESSAGE INTEGER :: I,IU,IOS,IOPT CHARACTER(LEN=256) :: FNAME,LINE LOGICAL :: LEX CALL WDIALOGSELECT(MESSAGE%WIN) SELECT CASE (ITYPE) CASE (PUSHBUTTON) SELECT CASE (MESSAGE%VALUE1) !## open configuration CASE (ID_OPEN1) IF(.NOT.UTL_WSELECTFILE('Load iMOD Batch File (*.ini)|*.ini|',& LOADDIALOG+PROMPTON+DIRCHANGE+APPENDEXT,FNAME,& 'Load iMOD Batch File (*.ini)'))RETURN 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 CREATE file called:'//CHAR(13)//& TRIM(FNAME),'Error') RETURN ENDIF !## check whether the function need to be used for plotting purposes LEX=.FALSE. IF(UTL_READINITFILE('CSVFNAME',LINE,IU,1))THEN READ(LINE,*) FNAME !## read the file - stop if there is a problem - fill in the dialog (in the back) IF(WBAL_ANALYSE_READCSV(FNAME))THEN LEX=WBAL_ANALYSE_READCONFIG(IU,0,IOPT) ENDIF ENDIF IF(.NOT.LEX)THEN CALL WMESSAGEBOX(OKONLY,EXCLAMATIONICON,COMMONOK,'iMOD cannot READ the file called:'//CHAR(13)//& TRIM(FNAME)//CHAR(13)//'correctly','Error') ENDIF CLOSE(IU) CALL WBAL_ANALYSE_TAB3_FIELD() !## open csv CASE (ID_OPEN2) IF(WBAL_ANALYSE_READCSV(''))THEN CALL WBAL_ANALYSE_TAB3_FIELD() ELSE CALL WBAL_ANALYSE_DEALLOCATE() ENDIF CASE (IDF_BUTTON3) !## export zone to IDF file and put it into the iMOD Manager IDFP%FNAME=TRIM(PREFVAL(1))//'\TMP\WATERBALANCE.IDF' IF(IDFWRITE(IDFP,IDFP%FNAME,0))CALL MANAGER_UTL_ADDFILE(IDFP%FNAME) !call idfplotfast() END SELECT CASE (FIELDCHANGED) SELECT CASE (MESSAGE%VALUE1) END SELECT SELECT CASE (MESSAGE%VALUE2) CASE (IDF_RADIO1,IDF_RADIO2) CALL WDIALOGGETRADIOBUTTON(MESSAGE%VALUE2,I) IF(I.EQ.1)THEN CALL WDIALOGFIELDSTATE(ID_OPEN1,1) CALL WDIALOGFIELDSTATE(ID_OPEN2,0) ELSE CALL WDIALOGFIELDSTATE(ID_OPEN1,0) CALL WDIALOGFIELDSTATE(ID_OPEN2,1) ENDIF END SELECT END SELECT END SUBROUTINE WBAL_ANALYSE_TAB1 !###====================================================================== SUBROUTINE WBAL_ANALYSE_TAB2(ITYPE,MESSAGE) !###====================================================================== IMPLICIT NONE INTEGER,INTENT(IN) :: ITYPE TYPE(WIN_MESSAGE),INTENT(IN) :: MESSAGE INTEGER :: IROW,ICOL,IRGB,I,J,IADD,IBAL CHARACTER(LEN=52) :: SEARCH CALL WDIALOGSELECT(MESSAGE%WIN) SELECT CASE (ITYPE) CASE (PUSHBUTTON) SELECT CASE (MESSAGE%VALUE1) CASE (IDF_MODFLOW,IDF_METASWAP) IF(MESSAGE%VALUE1.EQ.IDF_MODFLOW) J=1 IF(MESSAGE%VALUE1.EQ.IDF_METASWAP)J=2 DO I=1,SIZE(BUDGET) IBAL=WBAL_ANALYSE_GETBALANCETERM(BUDGET(I)%FLUXTERM) !## part of modflow-family IF(IBAL.GT.0.AND.IBAL.LE.SIZE(TP))THEN IF(TP(IBAL)%MODFLOWMETASWAP.EQ.J)BUDGET(I)%IACT=1 ENDIF ENDDO CALL WGRIDPUTCHECKBOX(IDF_GRID1,1,BUDGET%IACT,SIZE(BUDGET)) CASE (IDF_SELECTALL) BUDGET%IACT=1; CALL WGRIDPUTCHECKBOX(IDF_GRID1,1,BUDGET%IACT,SIZE(BUDGET)) CASE (IDF_DESELECTALL) BUDGET%IACT=0; CALL WGRIDPUTCHECKBOX(IDF_GRID1,1,BUDGET%IACT,SIZE(BUDGET)) CASE (IDF_SELECTALLDATES) LIDATE=1; CALL WDIALOGPUTMENU(IDF_MENU1,CIDATE,NDATE,LIDATE) CALL WBAL_ANALYSE_TAB3_FIELD() CASE (IDF_DESELECTALLDATES) LIDATE=0; CALL WDIALOGPUTMENU(IDF_MENU1,CIDATE,NDATE,LIDATE) !## budget wildcard selection CASE (ID_PLUS2,ID_MIN2) CALL WDIALOGGETSTRING(IDF_STRING2,SEARCH) DO I=1,SIZE(BUDGET) CALL WGRIDGETCELLSTRING (IDF_GRID1,2,I,BUDGET(I)%FLUXTERM) CALL WGRIDGETCELLCHECKBOX(IDF_GRID1,1,I,BUDGET(I)%IACT) ENDDO IADD=1; IF(MESSAGE%VALUE1.EQ.ID_MIN2)IADD=-1; CALL WBAL_FINDIT(BUDGET%FLUXTERM,BUDGET%IACT,SIZE(BUDGET),SEARCH,IADD) DO I=1,SIZE(BUDGET) CALL WGRIDPUTCELLCHECKBOX(IDF_GRID1,1,I,BUDGET(I)%IACT) ENDDO !## layer wildcard selection CASE (ID_PLUS1,ID_MIN1) CALL WDIALOGGETSTRING(IDF_STRING1,SEARCH) CALL WDIALOGGETMENU(IDF_MENU1,LIDATE) IADD=1; IF(MESSAGE%VALUE1.EQ.ID_MIN1)IADD=-1; CALL WBAL_FINDIT(CIDATE,LIDATE,NDATE,SEARCH,IADD) CALL WDIALOGPUTOPTION(IDF_MENU1,LIDATE) END SELECT CASE (FIELDCHANGED) SELECT CASE (MESSAGE%VALUE1) END SELECT SELECT CASE (MESSAGE%VALUE2) !## select period - check whether aggregration in time is possible - only for true dates CASE (IDF_MENU1) CALL WBAL_ANALYSE_TAB3_FIELD() CASE (IDF_GRID1) CALL WGRIDPOS(MESSAGE%Y,ICOL,IROW) IF(ICOL.EQ.3.AND.MESSAGE%Y.NE.MESSAGE%X)THEN CALL WGRIDGETCELLINTEGER(IDF_GRID1,3,IROW,IRGB) CALL WSELECTCOLOUR(IRGB) IF(WINFODIALOG(4).EQ.1)THEN CALL WGRIDPUTCELLINTEGER(IDF_GRID1,3,IROW,IRGB) CALL WGRIDCOLOURCELL( IDF_GRID1,3,IROW,IRGB,IRGB) BUDGET(IROW)%ICLR=IRGB ENDIF CALL WGRIDSETCELL(IDF_GRID1,1,IROW) ENDIF END SELECT END SELECT END SUBROUTINE WBAL_ANALYSE_TAB2 !###====================================================================== SUBROUTINE WBAL_ANALYSE_TAB3_FIELD() !###====================================================================== IMPLICIT NONE INTEGER :: I,J,IOS,IDATE CALL WDIALOGSELECT(ID_DWBAL_ANALYSE_TAB2) CALL WDIALOGGETMENU(IDF_MENU1,LIDATE) DO I=1,NDATE IF(LIDATE(I).EQ.0)CYCLE READ(CIDATE(I),*,IOSTAT=IOS) IDATE IF(IOS.NE.0)EXIT ENDDO J=1; IF(I.LE.NDATE)J=0 CALL WDIALOGSELECT(ID_DWBAL_ANALYSE_TAB3) CALL WDIALOGFIELDSTATE(IDF_RADIO5 ,J) CALL WDIALOGFIELDSTATE(IDF_RADIO6 ,J) CALL WDIALOGFIELDSTATE(IDF_RADIO7 ,J) CALL WDIALOGFIELDSTATE(IDF_RADIO8 ,J) CALL WDIALOGFIELDSTATE(IDF_RADIO9 ,J) CALL WDIALOGFIELDSTATE(IDF_RADIO10,J) CALL WDIALOGFIELDSTATE(IDF_RADIO11,J) CALL WDIALOGFIELDSTATE(IDF_RADIO12,J) END SUBROUTINE WBAL_ANALYSE_TAB3_FIELD !###====================================================================== SUBROUTINE WBAL_ANALYSE_TAB3(ITYPE,MESSAGE) !###====================================================================== IMPLICIT NONE INTEGER,INTENT(IN) :: ITYPE TYPE(WIN_MESSAGE),INTENT(IN) :: MESSAGE INTEGER :: IADD CHARACTER(LEN=52) :: SEARCH CALL WDIALOGSELECT(MESSAGE%WIN) SELECT CASE (ITYPE) CASE (PUSHBUTTON) SELECT CASE (MESSAGE%VALUE1) CASE (IDF_SELECTALLLAYERS) LILAY=1; CALL WDIALOGPUTMENU(IDF_MENU1,CILAY,NLAY,LILAY) CASE (IDF_DESELECTALLLAYERS) LILAY=0; CALL WDIALOGPUTMENU(IDF_MENU1,CILAY,NLAY,LILAY) CASE (IDF_SELECTALLZONES) LIZONE=1; CALL WDIALOGPUTMENU(IDF_MENU2,CIZONE,NZONE,LIZONE) CASE (IDF_DESELECTALLZONES) LIZONE=0; CALL WDIALOGPUTMENU(IDF_MENU2,CIZONE,NZONE,LIZONE) !## layer wildcard selection CASE (ID_PLUS2,ID_MIN2) CALL WDIALOGGETSTRING(IDF_STRING2,SEARCH) CALL WDIALOGGETMENU(IDF_MENU1,LILAY) IADD=1; IF(MESSAGE%VALUE1.EQ.ID_MIN2)IADD=-1; CALL WBAL_FINDIT(CILAY,LILAY,NLAY,SEARCH,IADD) CALL WDIALOGPUTOPTION(IDF_MENU1,LILAY) !## zone wildcard selection CASE (ID_PLUS1,ID_MIN1) CALL WDIALOGGETSTRING(IDF_STRING1,SEARCH) CALL WDIALOGGETMENU(IDF_MENU2,LIZONE) IADD=1; IF(MESSAGE%VALUE1.EQ.ID_MIN1)IADD=-1; CALL WBAL_FINDIT(CIZONE,LIZONE,NZONE,SEARCH,IADD) CALL WDIALOGPUTOPTION(IDF_MENU2,LIZONE) END SELECT CASE (FIELDCHANGED) SELECT CASE (MESSAGE%VALUE1) END SELECT SELECT CASE (MESSAGE%VALUE2) ! CASE (IDF_CHECK1) ! CALL WDIALOGGETCHECKBOX(IDF_CHECK1,I) ! I=ABS(I-1) ! !## inactivate graphical representation for net-fluxes ! CALL WDIALOGSELECT(ID_DWBAL_ANALYSE_TAB4) ! CALL WDIALOGFIELDSTATE(IDF_RADIO2,I) END SELECT END SELECT END SUBROUTINE WBAL_ANALYSE_TAB3 !###====================================================================== SUBROUTINE WBAL_ANALYSE_TAB4(ITYPE,MESSAGE) !###====================================================================== IMPLICIT NONE INTEGER,INTENT(IN) :: ITYPE TYPE(WIN_MESSAGE),INTENT(IN) :: MESSAGE INTEGER :: I,J,K,L CHARACTER(LEN=52) :: TEXT1,TEXT2 CHARACTER(LEN=256) :: DIR CALL WDIALOGSELECT(MESSAGE%WIN) SELECT CASE (ITYPE) CASE (PUSHBUTTON) SELECT CASE (MESSAGE%VALUE1) CASE (ID_OPEN1) !## get folder CALL WSELECTDIR(NONEXPATH+DIRCHANGE+DIRCREATE,DIR,'Select an output folder') IF(WINFODIALOG(4).EQ.1)CALL WDIALOGPUTSTRING(IDF_STRING1,TRIM(DIR)) CASE (ID_GRAPHICS,ID_PREVIEW) CALL WBAL_ANALYSE_PLOT(MESSAGE%VALUE1,0,'') END SELECT CASE (FIELDCHANGED) SELECT CASE (MESSAGE%VALUE1) END SELECT SELECT CASE (MESSAGE%VALUE2) CASE (IDF_RADIO1,IDF_RADIO2,IDF_RADIO3,IDF_RADIO4,IDF_RADIO5) CALL WDIALOGGETRADIOBUTTON(IDF_RADIO1,I) SELECT CASE (I) !## timeseries CASE (1); J=1; K=1; L=0; TEXT1='Generate Preview ...'; TEXT2='Generate Graphics' !## graphics CASE (2); J=1; K=1; L=1; TEXT1='Generate Preview ...'; TEXT2='Generate Graphics' !## table CASE (3); J=1; K=0; L=0; TEXT1='Generate Table'; TEXT2='Generate Graphics' !## export csv CASE (4); J=0; K=1; L=0; TEXT1='Generate Preview ...'; TEXT2='Export CSV-File ...' !## idf CASE (5); J=0; K=1; L=0; TEXT1='Generate Preview ...'; TEXT2='Export IDF-File ...' END SELECT CALL WDIALOGFIELDSTATE(ID_PREVIEW,J) CALL WDIALOGFIELDSTATE(ID_GRAPHICS,K) CALL WDIALOGFIELDSTATE(IDF_CHECK1,L) CALL WDIALOGFIELDSTATE(IDF_CHECK2,L) CALL WDIALOGFIELDSTATE(IDF_STRING2,L) IF(J.EQ.1)CALL WDIALOGPUTSTRING(ID_PREVIEW,TRIM(TEXT1)) IF(K.EQ.1)CALL WDIALOGPUTSTRING(ID_GRAPHICS,TRIM(TEXT2)) END SELECT END SELECT END SUBROUTINE WBAL_ANALYSE_TAB4 !###====================================================================== SUBROUTINE WBAL_ANALYSE_TAB5(ITYPE,MESSAGE) !###====================================================================== IMPLICIT NONE INTEGER,INTENT(IN) :: ITYPE TYPE(WIN_MESSAGE),INTENT(IN) :: MESSAGE CALL WDIALOGSELECT(MESSAGE%WIN) SELECT CASE (ITYPE) CASE (PUSHBUTTON) SELECT CASE (MESSAGE%VALUE1) END SELECT CASE (FIELDCHANGED) SELECT CASE (MESSAGE%VALUE1) END SELECT SELECT CASE (MESSAGE%VALUE2) CASE (IDF_MENU1) CALL WBAL_ANALYSE_TABLE_FILL() END SELECT END SELECT END SUBROUTINE WBAL_ANALYSE_TAB5 !###====================================================================== SUBROUTINE WBAL_FINDIT(LIST,ILIST,NLIST,SEARCH,IADD) !###====================================================================== IMPLICIT NONE CHARACTER(LEN=*),INTENT(IN),DIMENSION(NLIST) :: LIST INTEGER,INTENT(INOUT),DIMENSION(NLIST) :: ILIST INTEGER,INTENT(IN) :: NLIST,IADD CHARACTER(LEN=*),INTENT(IN) :: SEARCH INTEGER :: I DO I=1,NLIST IF(UTL_EQUALNAMES(SEARCH,LIST(I),ICAP=1))THEN !## remove from list IF(IADD.EQ.-1)ILIST(I)=0 !## add to list IF(IADD.EQ. 1)ILIST(I)=1 ENDIF ENDDO END SUBROUTINE WBAL_FINDIT !###====================================================================== LOGICAL FUNCTION WBAL_ANALYSE_READCSV(FNAME) !###====================================================================== IMPLICIT NONE CHARACTER(LEN=*),INTENT(IN) :: FNAME CHARACTER(LEN=5000) :: LINE CHARACTER(LEN=52) :: TXT INTEGER :: I,J,K,II,IU,IOS,SKIPLINES,IBAL INTEGER :: NV,NL WBAL_ANALYSE_READCSV=.TRUE. IF(LEN_TRIM(FNAME).EQ.0)THEN CSVFNAME='' IF(.NOT.UTL_WSELECTFILE('Load Comma Separated File (*.csv)|*.csv|',& LOADDIALOG+PROMPTON+DIRCHANGE+APPENDEXT,CSVFNAME,& 'Load Comma Separated File (*.csv)'))RETURN ELSE CSVFNAME=FNAME ENDIF IU=UTL_GETUNIT(); CALL OSD_OPEN(IU,FILE=CSVFNAME,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(CSVFNAME),'Error') RETURN ENDIF CALL UTL_MESSAGEHANDLE(0) !## define size of header SKIPLINES=0; DO READ(IU,'(A5000)',IOSTAT=IOS) LINE IF(IOS.NE.0)THEN CALL WMESSAGEBOX(OKONLY,EXCLAMATIONICON,COMMONOK,'iMOD cannot READ the file called:'//CHAR(13)//& TRIM(CSVFNAME)//CHAR(13)//' correctly. Probably this file is corrupt.','Error') RETURN ENDIF IF(UTL_CAP(LINE(1:4),'U').EQ.'DATE')EXIT; SKIPLINES=SKIPLINES+1 ENDDO !## check whether the string line was truly long enough IF(LINE(5000:5000).NE.'')THEN CALL WMESSAGEBOX(OKONLY,EXCLAMATIONICON,COMMONOK,'iMOD cannot read all the available columns in the CSV file'//CHAR(13)// & 'There is a maximum of 5000 character on a single line','Error') RETURN ENDIF !## number of budgetterms NV=UTL_COUNT_COLUMNS(LINE,',;'); NV=NV-4 !## allocate object, gwbal(1) is original gwbal(2) is selection to be processed as plot/graph CALL WBAL_ANALYSE_DEALLOCATE(); ALLOCATE(GWBAL(2)) WBAL_ANALYSE_READCSV=.FALSE. NBUDGET=NV/2 !## read labels of budgetterms ALLOCATE(GWBAL(1)%TXT(NV),GWBAL(2)%TXT(NV)) READ(LINE,*) TXT,TXT,TXT,TXT,(GWBAL(1)%TXT(I),I=1,NV) DO I=1,NV; GWBAL(2)%TXT(I)=GWBAL(1)%TXT(I); ENDDO ALLOCATE(BUDGET(NBUDGET)) J=0; K=0; DO I=1,NV,2 J=J+1; K=K+1 II=INDEX(GWBAL(1)%TXT(I),'_',.TRUE.) IF(II.GT.0)THEN BUDGET(J)%FLUXTERM=GWBAL(1)%TXT(I)(:II-1) ELSE BUDGET(J)%FLUXTERM=GWBAL(1)%TXT(I) ENDIF !## get existing waterbalance term and number IBAL=WBAL_ANALYSE_GETBALANCETERM(BUDGET(J)%FLUXTERM) IF(IBAL.GT.0)THEN BUDGET(J)%LABEL=UTL_CAP(TP(IBAL)%ALIAS,'L') BUDGET(J)%LABEL(1:1)=UTL_CAP(BUDGET(J)%LABEL(1:1),'U') ! !## plotgroup ! BUDGET(J)%IPLTGRP=WBAL_ANALYSE_GETPLTIGRP(BUDGET(IBAL)%ACRN) ELSE ! IF(GWBAL(1)%TXT(I).EQ.'BDGFUF')IBAL=10 !## insert appropriate budget number for fuf, ... BUDGET(J)%LABEL=GWBAL(1)%TXT(I) ! BUDGET(J)%IBAL=0 !IBAL ENDIF ! BUDGET(J)%FILE=GWBAL(1)%TXT(I) BUDGET(J)%ICLR=COLOUR_RANDOM() BUDGET(J)%IGROUP=J BUDGET(J)%IACT=1 ENDDO !## read to end of file NL=-1 DO READ(IU,*,IOSTAT=IOS) LINE IF(IOS.NE.0)EXIT IF(TRIM(LINE).EQ.'--------------------------------------------------')EXIT NL=NL+1 ENDDO !## allocate memory ALLOCATE(GWBAL(1)%CDATE(NL),GWBAL(1)%Q(NV,NL),GWBAL(1)%CLAY(NL),GWBAL(1)%CZONE(NL),GWBAL(1)%AREA(NL)) REWIND(IU) !## skip header DO I=1,SKIPLINES+2; READ(IU,'(A)') LINE; ENDDO !## read data entire data from csv DO I=1,NL READ(IU,*) GWBAL(1)%CDATE(I),GWBAL(1)%CLAY(I),GWBAL(1)%CZONE(I),GWBAL(1)%AREA(I),(GWBAL(1)%Q(J,I),J=1,NV) ENDDO !## try to read in zone-idf CALL IDFNULLIFY(IDFP) !## look for network dimensions DO I=1,3; READ(IU,*,IOSTAT=IOS); ENDDO IF(IOS.NE.0)THEN CLOSE(IU); CALL WMESSAGEBOX(OKONLY,EXCLAMATIONICON,COMMONNO,'Cannot read the selected CSV properly.'//CHAR(13)//'Probably missing information for the applied zone.','Error'); RETURN ENDIF IF(.NOT.IDFREADFREE(IU,IDFP,'T'))RETURN !## fill in sx,sy variables IF(.NOT.IDFFILLSXSY(IDFP))RETURN CLOSE(IU) ALLOCATE(CILAY(NL),CIZONE(NL),CIDATE(NL)) CILAY =GWBAL(1)%CLAY CIZONE=GWBAL(1)%CZONE CIDATE=GWBAL(1)%CDATE !## find how many dates CALL UTL_GETUNIQUE_CHAR(CIDATE,NL,NDATE) !## find how many layers CALL UTL_GETUNIQUE_CHAR(CILAY,NL,NLAY) !## find how many zones CALL UTL_GETUNIQUE_CHAR(CIZONE,NL,NZONE) !## print summary of csv on tab1 CALL WDIALOGSELECT(ID_DWBAL_ANALYSE_TAB1) CALL WDIALOGPUTINTEGER(IDF_INTEGER1,NBUDGET) !## unique budget terms CALL WDIALOGPUTINTEGER(IDF_INTEGER2,NDATE) !## unique period CALL WDIALOGPUTINTEGER(IDF_INTEGER3,NLAY) !## unique layers CALL WDIALOGPUTINTEGER(IDF_INTEGER4,NZONE) !## unique zones NRECORDS=NL; CALL WDIALOGPUTINTEGER(IDF_INTEGER5,NRECORDS) !## unique zones CALL WDIALOGPUTSTRING(IDF_STRING1,CSVFNAME) !## name of the csv CALL WDIALOGFIELDSTATE(IDF_BUTTON3,1) !## allocate menufield list indices ALLOCATE(LIDATE(NDATE),LIZONE(NZONE),CLRIZONE(NZONE),LILAY(NLAY)) !## none selected LIDATE=0; LIZONE=0; LILAY=0; CLRIZONE=0 IF(.NOT.WBAL_ANALYSE_FILLGRID())RETURN !## generate polygon colours IF(LEN_TRIM(FNAME).EQ.0)THEN DO I=1,NZONE; CLRIZONE(I)=COLOUR_RANDOM(); ENDDO ENDIF !## fill number of dates CALL WDIALOGSELECT(ID_DWBAL_ANALYSE_TAB2) CALL WDIALOGPUTMENU(IDF_MENU1,CIDATE,NDATE,LIDATE) !## fill number of layers/zones CALL WDIALOGSELECT(ID_DWBAL_ANALYSE_TAB3) CALL WDIALOGPUTMENU(IDF_MENU1,CILAY,NLAY,LILAY) CALL WDIALOGPUTMENU(IDF_MENU2,CIZONE,NZONE,LIZONE) !## outgrey tabstates CALL WDIALOGSELECT(ID_DWBAL_ANALYSE) CALL WDIALOGTABSTATE(IDF_TAB1,ID_DWBAL_ANALYSE_TAB2,1) CALL WDIALOGTABSTATE(IDF_TAB1,ID_DWBAL_ANALYSE_TAB3,1) CALL WDIALOGTABSTATE(IDF_TAB1,ID_DWBAL_ANALYSE_TAB4,1) CALL UTL_MESSAGEHANDLE(1) WBAL_ANALYSE_READCSV=.TRUE. END FUNCTION WBAL_ANALYSE_READCSV !###====================================================================== INTEGER FUNCTION WBAL_ANALYSE_GETBALANCETERM(TXT) !###====================================================================== IMPLICIT NONE CHARACTER(LEN=*),INTENT(IN) :: TXT INTEGER :: I,J WBAL_ANALYSE_GETBALANCETERM=0 J=INDEX(TXT,'_SYS'); IF(J.EQ.0)J=LEN_TRIM(TXT)+1; J=J-1 DO I=1,SIZE(TP) IF(TRIM(UTL_CAP(TXT(1:J),'U')).EQ.TRIM(UTL_CAP(TP(I)%ACRNM,'U')))EXIT ENDDO IF(I.LE.SIZE(TP))WBAL_ANALYSE_GETBALANCETERM=I END FUNCTION WBAL_ANALYSE_GETBALANCETERM !###====================================================================== INTEGER FUNCTION WBAL_ANALYSE_GETQCATEGORY(FLUXTERM) !###====================================================================== IMPLICIT NONE CHARACTER(LEN=*),INTENT(IN) :: FLUXTERM CHARACTER(LEN=52) :: FTERM INTEGER :: J WBAL_ANALYSE_GETQCATEGORY=0 FTERM=UTL_CAP(FLUXTERM,'U') J=INDEX(FTERM,'_SYS'); IF(J.EQ.0)J=LEN_TRIM(FTERM)+1; J=J-1 !## overrule for connected flows IF(INDEX(FTERM,'BDGFCF').GT.0)J=6 SELECT CASE (FTERM(1:J)) CASE ('BDGDRN'); WBAL_ANALYSE_GETQCATEGORY= 1 CASE ('BDGOLF'); WBAL_ANALYSE_GETQCATEGORY= 2 CASE ('BDGRIV'); WBAL_ANALYSE_GETQCATEGORY= 3 CASE ('BDGGHB'); WBAL_ANALYSE_GETQCATEGORY= 4 CASE ('BDGISG'); WBAL_ANALYSE_GETQCATEGORY= 5 CASE ('BDGWEL'); WBAL_ANALYSE_GETQCATEGORY= 6 CASE ('BDGFRF', & 'BDGFFF'); WBAL_ANALYSE_GETQCATEGORY= 7 CASE ('BDGBND'); WBAL_ANALYSE_GETQCATEGORY= 8 CASE ('BDGFLF'); WBAL_ANALYSE_GETQCATEGORY= 9 CASE ('BDGFTF'); WBAL_ANALYSE_GETQCATEGORY=10 CASE ('BDGRCH'); WBAL_ANALYSE_GETQCATEGORY=11 CASE ('BDGEVT'); WBAL_ANALYSE_GETQCATEGORY=12 CASE ('BDGCAP'); WBAL_ANALYSE_GETQCATEGORY=13 CASE ('BDGETACT'); WBAL_ANALYSE_GETQCATEGORY=14 CASE ('BDGPM'); WBAL_ANALYSE_GETQCATEGORY=15 CASE ('BDGPSGW'); WBAL_ANALYSE_GETQCATEGORY=16 CASE ('BDGPSSW'); WBAL_ANALYSE_GETQCATEGORY=17 CASE ('BDGSTO'); WBAL_ANALYSE_GETQCATEGORY=18 CASE ('BDGDECSTOT'); WBAL_ANALYSE_GETQCATEGORY=19 CASE ('BDGQSPGW'); WBAL_ANALYSE_GETQCATEGORY=20 CASE ('BDGQMODF'); WBAL_ANALYSE_GETQCATEGORY=21 CASE ('BDGQDR'); WBAL_ANALYSE_GETQCATEGORY=22 CASE ('BDGQRUN'); WBAL_ANALYSE_GETQCATEGORY=23 CASE ('MSW_QMODFBOT'); WBAL_ANALYSE_GETQCATEGORY=24 CASE ('BDGFCF'); WBAL_ANALYSE_GETQCATEGORY=-1 END SELECT ! DATA ICPL /08, & !## 01 drn ! 12, & !## 02 olf ! 09, & !## 03 riv ! 11, & !## 04 ghb ! 14, & !## 05 isg ! 07, & !## 06 wel ! 00, & !## 07 reg ---? ! 02, & !## 08 chh ! 03, & !## 09 flf ! 00, & !## 10 fuf ---? ! 13, & !## 11 rch ! 10, & !## 12 evt ! 15, & !## 13 cap ! 13, & !## 14 etact ! 00, & !## 15 pm ---? ! 24, & !## 16 pmgw (bdgpsgw) ! 35, & !## 17 pmsw (bdgpssw) ! 06, & !## 18 sto ! 34, & !## 19 decsto ! 30, & !## 20 bdgqspgw ! 00, & !## 21 qcor ! 00, & !## 22 qdr (bdgqdr) ! 00, & !## 23 qrun ! 00/ !## 24 qmodf END FUNCTION WBAL_ANALYSE_GETQCATEGORY !###====================================================================== LOGICAL FUNCTION WBAL_ANALYSE_FILLGRID() !###====================================================================== IMPLICIT NONE INTEGER :: I,NROW WBAL_ANALYSE_FILLGRID=.FALSE. !## fill grid CALL WDIALOGSELECT(ID_DWBAL_ANALYSE_TAB2) NROW=WINFOGRID(IDF_GRID1,GRIDROWSMAX) IF(SIZE(BUDGET).GT.NROW)THEN CALL WMESSAGEBOX(OKONLY,EXCLAMATIONICON,COMMONOK,'iMOD can store maximal number of '//TRIM(ITOS(NROW))//' waterbalance terms.'//CHAR(13)// & 'The number of waterbalance terms in te selected csv-file is '//TRIM(ITOS(SIZE(BUDGET))),'Error') RETURN ENDIF CALL WGRIDROWS(IDF_GRID1,SIZE(BUDGET)) DO I=1,SIZE(BUDGET) CALL WGRIDPUTCELLCHECKBOX(IDF_GRID1,1,I,BUDGET(I)%IACT) CALL WGRIDPUTCELLSTRING( IDF_GRID1,2,I,BUDGET(I)%FLUXTERM) CALL WGRIDPUTCELLINTEGER( IDF_GRID1,3,I,BUDGET(I)%ICLR) CALL WGRIDCOLOURCELL( IDF_GRID1,3,I,BUDGET(I)%ICLR,BUDGET(I)%ICLR) CALL WGRIDPUTCELLSTRING( IDF_GRID1,4,I,BUDGET(I)%LABEL) CALL WGRIDPUTCELLINTEGER( IDF_GRID1,5,I,BUDGET(I)%IGROUP) ENDDO WBAL_ANALYSE_FILLGRID=.TRUE. END FUNCTION WBAL_ANALYSE_FILLGRID !###====================================================================== SUBROUTINE WBAL_ANALYSE_PLOT(ID,IBATCH,OUTPUTFNAME) !###====================================================================== IMPLICIT NONE INTEGER,INTENT(IN) :: ID,IBATCH CHARACTER(LEN=*) :: OUTPUTFNAME INTEGER :: IOPT,IG,I1,I2,N,IUNIT,IGG,ITYPE,IEXIT CHARACTER(LEN=256) :: DIR,GTITLE,FNAME LOGICAL :: LSUM,LEXPORT TYPE(WIN_MESSAGE) :: MESSAGE !## get option from the window to determine what to do CALL WDIALOGSELECT(ID_DWBAL_ANALYSE_TAB4) !## output type CALL WDIALOGGETRADIOBUTTON(IDF_RADIO1,IOPT) !## get the appropriate selection IF(.NOT.WBAL_ANAYSE_PREPARE(IOPT,IUNIT,LSUM))RETURN CALL WDIALOGSELECT(ID_DWBAL_ANALYSE_TAB4) GTITLE='Balance $'; IF(IBATCH.EQ.0)CALL WDIALOGGETSTRING(IDF_STRING2,GTITLE) IF(ID.EQ.ID_GRAPHICS)THEN !## will be an existing folder CALL WDIALOGGETSTRING(IDF_STRING1,DIR) IF(LEN_TRIM(DIR).EQ.0)THEN CALL WMESSAGEBOX(YESNOCANCEL,QUESTIONICON,COMMONNO,'There is no output folder specified.'//CHAR(13)// & 'Do you want to continue and use the following outut folder:'//CHAR(13)//TRIM(PREFVAL(1))//'\tmp ?','Question') IF(WINFODIALOG(4).NE.1)RETURN DIR=TRIM(PREFVAL(1))//'\tmp' ENDIF ENDIF SELECT CASE (IOPT) !## timeseries CASE (1) !## in graph plot optie maken om de bmp te saven en terug te keren - loop of GRAPHDIM%GRAPHNAMES() met name LEXPORT=.FALSE.; IF(ID.EQ.ID_GRAPHICS)LEXPORT=.TRUE. CALL GRAPH_INIT(3,LEXPORT=LEXPORT,DIR=DIR,IBATCH=IBATCH) IF(IBATCH.EQ.0)THEN DO CALL WMESSAGE(ITYPE,MESSAGE) CALL GRAPH_MAIN(ITYPE,MESSAGE,IEXIT=IEXIT) IF(IEXIT.EQ.1)EXIT ENDDO ENDIF !## graph CASE (2) N=SIZE(GRAPH(1,1)%RY)+SIZE(GRAPHDIM%GRAPHNAMES) IF(N.GT.25)THEN IF(ID.EQ.ID_GRAPHICS)THEN CALL WMESSAGEBOX(YESNOCANCEL,QUESTIONICON,COMMONNO,'Are you sure to EXPORT '//TRIM(ITOS(N))//' images ?','Question') ELSE CALL WMESSAGEBOX(YESNOCANCEL,QUESTIONICON,COMMONNO,'Are you sure to DISPLAY '//TRIM(ITOS(N))//' images sequentially ?','Question') ENDIF IF(WINFODIALOG(4).NE.1)RETURN ENDIF CALL WDIALOGSELECT(ID_DWBAL_ANALYSE_TAB4) CALL WDIALOGGETCHECKBOX(IDF_CHECK1,I1) CALL WDIALOGGETCHECKBOX(IDF_CHECK2,I2) IF(ID.EQ.ID_GRAPHICS)CALL UTL_MESSAGEHANDLE(0) IGG=0; DO IG=1,SIZE(GRAPHDIM%GRAPHNAMES) IGG=IGG+1; IF(IGG.GT.MZONE)IGG=1 IF(.NOT.WBAL_ANALYSE_PLOTIMAGE(ID,IG,IGG,I1,I2,DIR,GTITLE,IUNIT,LSUM))EXIT ENDDO IF(ID.EQ.ID_GRAPHICS)THEN CALL UTL_MESSAGEHANDLE(1) IF(IBATCH.EQ.0)THEN CALL WMESSAGEBOX(OKONLY,INFORMATIONICON,COMMONOK,'iMOD SAVED (all) the requested bitmaps in the folder:'//CHAR(13)//& TRIM(DIR)//'\FIGURE_*.PNG'//CHAR(13)//'successfully.','Information') ELSE WRITE(*,'(/A/)') 'iMOD SAVED (all) the requested bitmaps in the folder: '//TRIM(DIR)//'\FIGURE_*.PNG' ENDIF ENDIF !## table CASE (3) IF(WBAL_ANALYSE_TABLE())THEN CALL WDIALOGSELECT(ID_DWBAL_ANALYSE) CALL WDIALOGSETTAB(IDF_TAB1,ID_DWBAL_ANALYSE_TAB5) ENDIF !## save to csv CASE (4) if(IBATCH.EQ.0)THEN FNAME='' ELSE FNAME=OUTPUTFNAME ENDIF IF(WBAL_ANALYSE_EXPORTCSV(FNAME))THEN; ENDIF !## save to idf files - no preview CASE (5) IF(WBAL_ANALYSE_EXPORTIDF())THEN; ENDIF END SELECT CALL WDIALOGSELECT(ID_DWBAL_ANALYSE_TAB4) END SUBROUTINE WBAL_ANALYSE_PLOT !###====================================================================== LOGICAL FUNCTION WBAL_ANAYSE_PREPARE(IOPT,IUNIT,LLSUM) !###====================================================================== IMPLICIT NONE INTEGER,INTENT(IN) :: IOPT INTEGER,INTENT(OUT) :: IUNIT LOGICAL,INTENT(OUT) :: LLSUM INTEGER :: I,J,K,IL,IZ,ID,IG,IQIN,IQOU,JQIN,JQOU,IQ,IIQ,JQ,IOS,IDATE,ITTYPE,IHIT, & IAG,NXG,IY1,IM1,ID1,IY2,IM2,ID2,IPOS,SDATE,IB,LSUM,ZSUM,N,INET,NUQ,PQ REAL(KIND=DP_KIND),POINTER,DIMENSION(:) :: DT CHARACTER(LEN=16),POINTER,DIMENSION(:) :: XTXT=>NULL() CHARACTER(LEN=16) :: TXTL,TXTZ,TUNIT,LUNIT INTEGER,ALLOCATABLE,DIMENSION(:) :: IDATES,SQ,UQ,OSQ,OQ REAL(KIND=DP_KIND) :: QIN,QOU,Q WBAL_ANAYSE_PREPARE=.FALSE. IF(ALLOCATED(GRAPH))CALL GRAPH_DEALLOCATE() !## get selected dates CALL WDIALOGSELECT(ID_DWBAL_ANALYSE_TAB2) CALL WDIALOGGETMENU(IDF_MENU1,LIDATE) !## select m3/d or mm/d CALL WDIALOGGETRADIOBUTTON(IDF_RADIO1,IUNIT) !## get selected budgets DO I=1,SIZE(BUDGET) CALL WGRIDGETCELLCHECKBOX(IDF_GRID1,1,I,BUDGET(I)%IACT) CALL WGRIDGETCELLSTRING( IDF_GRID1,2,I,BUDGET(I)%FLUXTERM) CALL WGRIDGETCELLINTEGER( IDF_GRID1,3,I,BUDGET(I)%ICLR) CALL WGRIDGETCELLSTRING( IDF_GRID1,4,I,BUDGET(I)%LABEL) CALL WGRIDGETCELLINTEGER( IDF_GRID1,5,I,BUDGET(I)%IGROUP) ENDDO CALL WDIALOGSELECT(ID_DWBAL_ANALYSE_TAB3) !## get selected layers CALL WDIALOGGETMENU(IDF_MENU1,LILAY) !## sum layers CALL WDIALOGGETRADIOBUTTON(IDF_RADIO3,LSUM); LSUM=LSUM-1 !## get selected zones CALL WDIALOGGETMENU(IDF_MENU2,LIZONE) !## sum zones CALL WDIALOGGETRADIOBUTTON(IDF_RADIO1,ZSUM); ZSUM=ZSUM-1 !## zones are summed LLSUM=.FALSE.; IF(ZSUM.EQ.1)LLSUM=.TRUE. !## check whether selectable IAG=0; IF(WINFODIALOGFIELD(IDF_RADIO5,FIELDSTATE).EQ.1)CALL WDIALOGGETRADIOBUTTON(IDF_RADIO5,IAG) !## apply net fluxes CALL WDIALOGGETCHECKBOX(IDF_CHECK1,INET) !## make selection MLAY=0; DO I=1,NLAY; IF(LILAY(I).EQ.1) MLAY=MLAY+1; ENDDO MZONE=0; DO I=1,NZONE; IF(LIZONE(I).EQ.1) MZONE=MZONE+1; ENDDO MDATE=0; DO I=1,NDATE; IF(LIDATE(I).EQ.1) MDATE=MDATE+1; ENDDO MBUDGET=0; DO I=1,NBUDGET; IF(BUDGET(I)%IACT.EQ.1)MBUDGET=MBUDGET+1; ENDDO !## get appropriate sort ALLOCATE(SQ(MBUDGET),UQ(MBUDGET),OSQ(MBUDGET),OQ(MBUDGET)) IQ=0; DO I=1,NBUDGET IF(BUDGET(I)%IACT.EQ.0)CYCLE IQ=IQ+1 UQ(IQ)=BUDGET(I)%IGROUP OQ(IQ)=I ENDDO SQ=UQ !## get number of unique budget terms (groups) CALL UTL_GETUNIQUE_INT(UQ,MBUDGET,NUQ,-9999) !## it is not allowed to aggregrate budgetterms for graphical representations IF(IOPT.EQ.2)THEN IF(NUQ.NE.MBUDGET)THEN DEALLOCATE(SQ,UQ,OSQ,OQ) CALL WMESSAGEBOX(OKONLY,EXCLAMATIONICON,COMMONOK,'It is not allowed to group budget terms for the graphical representation','Information') RETURN ENDIF ENDIF !## get appropriate sort order osq CALL WSORT(SQ,1,MBUDGET,IORDER=OSQ) !## number of budget in the graphs (unique groups times 2 - in- and outflow) MBUDGET=NUQ*2 !## total groups in potential MGROUP=MZONE*MLAY IF(MGROUP.EQ.0.OR.MBUDGET.EQ.0.OR.MDATE.EQ.0)THEN DEALLOCATE(SQ,UQ,OSQ,OQ) CALL WMESSAGEBOX(OKONLY,EXCLAMATIONICON,COMMONOK,'There is nothing selected to generate a water balance for.'//CHAR(13)// & 'Go to the tabs BUDGET TERMS and/or AGGREGATION to make an appropriate selection(s).','Information') RETURN ENDIF !## allocate memory for selected items ALLOCATE(CMDATE(MDATE),CMLAY(MLAY),CMZONE(MZONE)); CMDATE=''; CMLAY=''; CMZONE='' J=0; DO I=1,NLAY; IF(LILAY(I).EQ.1)THEN J=J+1; CMLAY(J)=CILAY(I) ENDIF; ENDDO J=0; DO I=1,NZONE; IF(LIZONE(I).EQ.1)THEN J=J+1; CMZONE(J)=CIZONE(I) ENDIF; ENDDO ITTYPE=0; J=0; DO I=1,NDATE; IF(LIDATE(I).EQ.1)THEN J=J+1; CMDATE(J)=CIDATE(I) !## check whether all dates are convertable IF(ITTYPE.EQ.0)THEN READ(CIDATE(I),*,IOSTAT=IOS) IDATE IF(IOS.NE.0)ITTYPE=1 ENDIF ENDIF; ENDDO !## get number of years, months, decades (mindate/maxdate) IF(ITTYPE.EQ.0)THEN READ(CMDATE(1),*) IDATE; CALL IDATETOGDATE(IDATE,IY1,IM1,ID1) READ(CMDATE(SIZE(CMDATE)),*) IDATE; CALL IDATETOGDATE(IDATE,IY2,IM2,ID2) !## define nxg, dt, sdate en xtxt for aggregration SELECT CASE (IAG) !## all CASE (1); NXG=WBAL_ANAYSE_PREPARE_GETALL(IY1,IM1,ID1,IY2,IM2,ID2,SDATE,DT,XTXT); TUNIT='d' !## year CASE (2); NXG=WBAL_ANAYSE_PREPARE_GETYEAR(IM1,ID1,IY1,IY2,SDATE,DT,XTXT); TUNIT='year' !## months CASE (3); NXG=WBAL_ANAYSE_PREPARE_GETMONTHS(IY1,IM1,IY2,IM2,SDATE,DT,XTXT); TUNIT='month' !## hydrologic seasons CASE (4); NXG=WBAL_ANAYSE_PREPARE_GETHSEASON(IY1,IM1,IY2,IM2,SDATE,DT,XTXT); TUNIT='hseason' !## decade CASE (5); NXG=WBAL_ANAYSE_PREPARE_GETDECADES(IY1,IM1,ID1,IY2,IM2,ID2,SDATE,DT,XTXT); TUNIT='decade' !## hydrological year CASE (6); NXG=WBAL_ANAYSE_PREPARE_GETHYEAR(IY1,IM1,IY2,IM2,SDATE,DT,XTXT); TUNIT='hyear' !## quarters CASE (7); NXG=WBAL_ANAYSE_PREPARE_GETQUARTERS(IY1,IM1,IY2,IM2,SDATE,DT,XTXT); TUNIT='quarteryear' !## none - true dates in the result array CASE (8); NXG=WBAL_ANAYSE_PREPARE_GETSELDATES(CMDATE,SDATE,DT,XTXT); TUNIT='d' END SELECT ALLOCATE(IDATES(NXG+1)); IDATES=0 ELSE !## steady-state (or equivalent defined by periods) NXG=J; ALLOCATE(IDATES(NXG)); IDATES=0 ALLOCATE(DT(NXG),XTXT(NXG)) DO I=1,NXG; DT(I)=1.0D0; XTXT(I)=CMDATE(I); ENDDO TUNIT='-' ENDIF LUNIT='m3'; IF(IUNIT.EQ.2)LUNIT='mm' !## if zones need to be summed, overrule number of zones I=MZONE; IF(ZSUM.EQ.1)I=1 !## if layers need to be summed, overrule number of layers J=MLAY; IF(LSUM.EQ.1)J=1 !## total groups in graph MGROUP=I*J !## allocate graph memory CALL GRAPH_ALLOCATE(MBUDGET,MGROUP) DO I=1,MBUDGET; DO J=1,MGROUP ALLOCATE(GRAPH(I,J)%RX(NXG),GRAPH(I,J)%RY(NXG)) GRAPH(I,J)%RX=0.0D0; GRAPH(I,J)%RY=0.0D0; GRAPH(I,J)%NP=NXG; GRAPH(I,J)%CTYPE=''; GRAPH(I,J)%ICLR=0 ENDDO; ENDDO !## add custom predefined axes titles DO I=1,MGROUP GRAPHDIM(I)%IFIXX=1 !GRAPHDIM(I)%IFIXX=0; GRAPHDIM(I)%IFIXY=0; GRAPHDIM(I)%LDATE=.FALSE. ALLOCATE(GRAPHDIM(I)%XTXT(NXG),GRAPHDIM(I)%XPOS(NXG)); GRAPHDIM(I)%XTXT=''; GRAPHDIM(I)%XPOS=0.0D0 !; IF(ITTYPE.EQ.1)GRAPHDIM(I)%IFIXX=1 GRAPHDIM(I)%IGROUP=1 ! IF(ITTYPE.EQ.0)THEN; SELECT CASE (IAG); CASE(8); GRAPHDIM(I)%LDATE=.TRUE.; END SELECT; ENDIF ENDDO !### use dt to create rdates array CALL WBAL_ANALYSE_PREPARERDATES(ITTYPE,SDATE,DT,XTXT,IDATES) !## set axes dimensions DO I=1,MGROUP GRAPHDIM(I)%XINT=1.0D0; GRAPHDIM(I)%XMIN=GRAPHDIM(I)%XPOS(1)-1.0D0; GRAPHDIM(I)%XMAX=GRAPHDIM(I)%XPOS(NXG)+1.0D0 !## all stacked histograms GRAPH(:,I)%GTYPE =3 !## set graph title IF(IUNIT.EQ.1)THEN GRAPHDIM(I)%YTITLE='Volumes ('//TRIM(LUNIT)//'/'//TRIM(TUNIT)//')' ELSEIF(IUNIT.EQ.2)THEN GRAPHDIM(I)%YTITLE='Quantity ('//TRIM(LUNIT)//'/'//TRIM(TUNIT)//')' ENDIF GRAPHDIM(I)%XTITLE='('//TRIM(TUNIT)//')' GRAPHDIM(I)%TEXTSIZE=5.0D0 ENDDO !## remove memory of dt IF(ASSOCIATED(DT)) DEALLOCATE(DT) IF(ASSOCIATED(XTXT))DEALLOCATE(XTXT) !## copy selected layers/zones for summing purposes IF(ALLOCATED(CLILAY))DEALLOCATE(CLILAY) IF(ALLOCATED(CLIZONE))DEALLOCATE(CLIZONE) ALLOCATE(CLILAY(NLAY)); DO I=1,NLAY; CLILAY(I) =LILAY(I); ENDDO ALLOCATE(CLIZONE(NZONE)); DO I=1,NZONE; CLIZONE(I)=LIZONE(I); ENDDO !## turn layers/zones and active only one for summing purposes IF(LSUM.EQ.1)THEN; CLILAY=0; CLILAY(1)=1; ENDIF IF(ZSUM.EQ.1)THEN; CLIZONE=0; CLIZONE(1)=1; ENDIF !## assign label name for each group (= zone and layer) K=0; DO I=1,NLAY; DO J=1,NZONE IF(CLILAY(I).EQ.0)CYCLE IF(CLIZONE(J).EQ.0)CYCLE K=K+1 TXTL='Layer '//TRIM(CILAY(I)); IF(LSUM.EQ.1)TXTL='Layer [sum]' TXTZ='Zone '//TRIM(CIZONE(J)); IF(ZSUM.EQ.1)TXTZ='Zone [sum]' GRAPHDIM(K)%GRAPHNAMES=TRIM(TXTL)//'; '//TRIM(TXTZ) ENDDO; ENDDO !## gather main information JQ=0; DO IIQ=1,SIZE(OSQ) !## function of group number and therefore defines sort-order IQ=OQ(OSQ(IIQ)) !## previous budget terms IF(IIQ.GT.1)THEN PQ=OQ(OSQ(IIQ-1)); IF(BUDGET(PQ)%IGROUP.NE.BUDGET(IQ)%IGROUP)JQ=JQ+1 ELSE !## increase only whenever different group starts JQ=JQ+1 ENDIF IG=0; DO J=1,NZONE; DO I=1,NLAY IF(CLILAY(I).EQ.0)CYCLE IF(CLIZONE(J).EQ.0)CYCLE IG=IG+1 JQIN=(JQ-1)*2+1 JQOU= JQIN+1 !## plot legend one-by-one GRAPH(JQOU,IG)%LEGTXT='' !## if export to idf assign legend text for both as used for the filename IF(IOPT.EQ.5)GRAPH(JQOU,IG)%LEGTXT=TRIM(UTL_CAP(BUDGET(IQ)%LABEL,'U')) GRAPH(JQIN,IG)%LEGTXT=TRIM(UTL_CAP(BUDGET(IQ)%LABEL,'U')) GRAPH(JQOU,IG)%ICLR =BUDGET(IQ)%ICLR GRAPH(JQIN,IG)%ICLR =BUDGET(IQ)%ICLR IF(TRIM(GRAPH(JQIN,IG)%CTYPE).EQ.'')THEN GRAPH(JQOU,IG)%CTYPE =TRIM(UTL_CAP(BUDGET(IQ)%FLUXTERM,'U')) GRAPH(JQIN,IG)%CTYPE =TRIM(UTL_CAP(BUDGET(IQ)%FLUXTERM,'U')) ENDIF ENDDO; ENDDO ENDDO !## fill in in advance the horizontal position DO I=1,SIZE(GRAPH,1); DO J=1,SIZE(GRAPH,2) DO IPOS=1,SIZE(GRAPH(I,J)%RX) GRAPH(I,J)%RX(IPOS)=REAL(IPOS) ! GRAPH(I,J)%RX(IPOS)=REAL(IPOS) ENDDO ENDDO; ENDDO CALL UTL_MESSAGEHANDLE(0) !## gather data IHIT=0; DO I=1,NRECORDS !## appropriate item IF(.NOT.WBAL_ANALYSE_SELECT(GWBAL(1)%CLAY(I),GWBAL(1)%CZONE(I),GWBAL(1)%CDATE(I),IL,IZ,ID,IAG,IPOS,IDATES))CYCLE ! !## sum for layers ! N=MLAY; IF(LSUM.EQ.1)THEN; IL=1; N=1; ENDIF ! !## sum for zones ! IF(ZSUM.EQ.1)IZ=1 !## sum for layers N=MZONE; IF(ZSUM.EQ.1)THEN; IZ=1; N=1; ENDIF !## sum for zones IF(LSUM.EQ.1)IL=1 !## get appropriate group number IG=(IL-1)*N+IZ JQIN=-1; JQOU=0; JQ=0 DO IIQ=1,SIZE(OSQ) !## function of group number and therefore defines sort-order IQ=OQ(OSQ(IIQ)) !## previous budget terms IF(IIQ.GT.1)THEN PQ=OQ(OSQ(IIQ-1)); IF(BUDGET(PQ)%IGROUP.NE.BUDGET(IQ)%IGROUP)JQ=JQ+1 ELSE !## increase only whenever different group starts JQ=JQ+1 ENDIF IHIT=IHIT+1 JQIN=(JQ-1)*2+1 JQOU= JQIN+1 IQIN=(IQ-1)*2+1 IQOU= IQIN+1 !## get balance value QIN=GWBAL(1)%Q(IQIN,I) QOU=GWBAL(1)%Q(IQOU,I) !## convert m3/d to mm/d IF(IUNIT.EQ.2)THEN QIN=QIN/(1000.0D0*GWBAL(1)%AREA(I)) QOU=QOU/(1000.0D0*GWBAL(1)%AREA(I)) ENDIF !## add to existing fluxes - ID is timestep GRAPH(JQIN,IG)%RY(IPOS)=GRAPH(JQIN,IG)%RY(IPOS)+QIN GRAPH(JQOU,IG)%RY(IPOS)=GRAPH(JQOU,IG)%RY(IPOS)+QOU ENDDO ENDDO CALL UTL_MESSAGEHANDLE(1) DEALLOCATE(CMDATE,CMLAY,CMZONE,IDATES,SQ,UQ,OSQ,OQ) !## make stacked-histograms DO ID=1,NXG DO IG=1,MGROUP !## compute net fluxes IF(INET.EQ.1)THEN DO IB=1,MBUDGET,2 Q=GRAPH(IB ,IG)%RY(ID)+GRAPH(IB+1,IG)%RY(ID) GRAPH(IB ,IG)%RY(ID)=0.0D0 GRAPH(IB+1,IG)%RY(ID)=0.0D0 IF(Q.GT.0.0D0)GRAPH(IB ,IG)%RY(ID)=Q IF(Q.LT.0.0D0)GRAPH(IB+1,IG)%RY(ID)=Q ENDDO ENDIF !## aggregate IF(IOPT.EQ.1)THEN DO IB=3,MBUDGET,2 !## in GRAPH(IB ,IG)%RY(ID)=GRAPH(IB ,IG)%RY(ID)+GRAPH(IB-2,IG)%RY(ID) !## out GRAPH(IB+1,IG)%RY(ID)=GRAPH(IB+1,IG)%RY(ID)+GRAPH(IB-1,IG)%RY(ID) ENDDO ENDIF ENDDO ENDDO IF(IHIT.EQ.0)THEN CALL WMESSAGEBOX(OKONLY,INFORMATIONICON,COMMONOK,'There remains nothing to generate a water balance for.'//CHAR(13)// & 'Go to the tabs BUDGET TERMS and AGGREGATION to make an appropriate selection.','Information') RETURN ENDIF WBAL_ANAYSE_PREPARE=.TRUE. END FUNCTION WBAL_ANAYSE_PREPARE !###====================================================================== SUBROUTINE WBAL_ANALYSE_PREPARERDATES(ITTYPE,SDATE,DT,XTXT,IDATES) !###====================================================================== IMPLICIT NONE INTEGER,INTENT(IN) :: SDATE,ITTYPE INTEGER,INTENT(OUT),DIMENSION(:) :: IDATES REAL(KIND=DP_KIND),POINTER,INTENT(IN),DIMENSION(:) :: DT CHARACTER(LEN=*),INTENT(INOUT),DIMENSION(:),POINTER :: XTXT INTEGER :: I,J !## real time (julian dates) IF(ITTYPE.EQ.0)THEN IDATES(1)=SDATE DO I=1,SIZE(DT) J=UTL_IDATETOJDATE(IDATES(I))+DT(I) IDATES(I+1)=UTL_JDATETOIDATE(J) GRAPHDIM(:)%XTXT(I)=XTXT(I) GRAPHDIM(:)%XPOS(I)=REAL(I) ENDDO ELSE DO I=1,SIZE(DT) GRAPHDIM(:)%XTXT(I)=XTXT(I) GRAPHDIM(:)%XPOS(I)=REAL(I) ENDDO ENDIF END SUBROUTINE WBAL_ANALYSE_PREPARERDATES !###====================================================================== INTEGER FUNCTION WBAL_ANAYSE_PREPARE_GETSELDATES(CMDATE,SDATE,DT,XTXT) !###====================================================================== IMPLICIT NONE CHARACTER(LEN=*),DIMENSION(:),INTENT(IN) :: CMDATE REAL(KIND=DP_KIND),INTENT(OUT),DIMENSION(:),POINTER :: DT CHARACTER(LEN=*),INTENT(OUT),DIMENSION(:),POINTER :: XTXT INTEGER,INTENT(OUT) :: SDATE INTEGER :: I,ND,IDATE,JDATE !## set start date READ(CMDATE(1),*) SDATE ND=SIZE(CMDATE); ALLOCATE(DT(ND),XTXT(ND)); DT=0.0D0; XTXT='' ND=0; DO I=1,SIZE(CMDATE) ND=ND+1 READ(CMDATE(I),*) IDATE JDATE=IDATE; IF(I.LT.SIZE(CMDATE))READ(CMDATE(I+1),*) JDATE DT(I) =UTL_IDATETOJDATE(JDATE)-UTL_IDATETOJDATE(IDATE) !+1.0D0 XTXT(I)=TRIM(ITOS(IDATE)) ENDDO WBAL_ANAYSE_PREPARE_GETSELDATES=ND END FUNCTION WBAL_ANAYSE_PREPARE_GETSELDATES !###====================================================================== INTEGER FUNCTION WBAL_ANAYSE_PREPARE_GETALL(IY1,IM1,ID1,IY2,IM2,ID2,SDATE,DT,XTXT) !###====================================================================== IMPLICIT NONE INTEGER,INTENT(IN) :: IY1,IM1,ID1,IY2,IM2,ID2 INTEGER,INTENT(OUT) :: SDATE REAL(KIND=DP_KIND),INTENT(OUT),DIMENSION(:),POINTER :: DT CHARACTER(LEN=*),INTENT(OUT),DIMENSION(:),POINTER :: XTXT INTEGER :: EDATE !## set start date SDATE=IY1*10000+IM1*100+ID1 !## set end date EDATE=IY2*10000+IM2*100+ID2 ALLOCATE(DT(1),XTXT(1)); DT=0.0D0; XTXT=TRIM(ITOS(SDATE))//'-'//TRIM(ITOS(EDATE)) DT(1)=(UTL_IDATETOJDATE(EDATE)-UTL_IDATETOJDATE(SDATE))+1.0D0 WBAL_ANAYSE_PREPARE_GETALL=1 END FUNCTION WBAL_ANAYSE_PREPARE_GETALL !###====================================================================== INTEGER FUNCTION WBAL_ANAYSE_PREPARE_GETYEAR(IM1,ID1,IY1,IY2,SDATE,DT,XTXT) !###====================================================================== IMPLICIT NONE INTEGER,INTENT(IN) :: IY1,IY2,IM1,ID1 INTEGER,INTENT(OUT) :: SDATE REAL(KIND=DP_KIND),INTENT(OUT),DIMENSION(:),POINTER :: DT CHARACTER(LEN=*),INTENT(OUT),DIMENSION(:),POINTER :: XTXT INTEGER :: I,NY,IY !## set start date SDATE=IY1*10000+IM1*100+ID1 !## get number of months NY=(IY2-IY1)+1 !## define dt pointer ALLOCATE(DT(NY),XTXT(NY)); XTXT=''; DT=0.0D0 IY=IY1; DO I=1,NY DT(I)=365.0D0; IF(WDATELEAPYEAR(IY))DT(I)=DT(I)+1.0D0 XTXT(I)=TRIM(ITOS(IY)) !//'0000' IY=IY+1 ENDDO WBAL_ANAYSE_PREPARE_GETYEAR=NY END FUNCTION WBAL_ANAYSE_PREPARE_GETYEAR !###====================================================================== INTEGER FUNCTION WBAL_ANAYSE_PREPARE_GETHYEAR(IY1,IM1,IY2,IM2,SDATE,DT,XTXT) !###====================================================================== IMPLICIT NONE INTEGER,INTENT(IN) :: IY1,IM1,IY2,IM2 INTEGER,INTENT(OUT) :: SDATE REAL(KIND=DP_KIND),INTENT(OUT),DIMENSION(:),POINTER :: DT CHARACTER(LEN=*),INTENT(OUT),DIMENSION(:),POINTER :: XTXT INTEGER :: I,J,ND,IY,IM,ID,IDATE,EDATE,IYY,IMM !## four seasons 1/12 - 28/2 !## 1/3 - 31/5 !## 1/6 - 31/8 !## 1/9 - 30/11 !## set start date - clipped to first of month ID=1; IY=IY1 IF(IM1.EQ.12.OR.IM1.LE.2)THEN IM=12; IF(IM1.LE.2)IY=IY-1 ELSEIF(IM1.GE.3.AND.IM1.LE.5)THEN IM=3 ELSEIF(IM1.GE.6.AND.IM1.LE.8)THEN IM=6 ELSE IM=9 ENDIF SDATE=IY*10000+IM*100+ID IYY=IY IMM=IM !## set end date - rounded to end of month IY=IY2 IF(IM2.EQ.12.OR.IM2.LE.2)THEN IM=2; IF(IM2.EQ.12)IY=IY+1 ELSEIF(IM2.GE.3.AND.IM2.LE.5)THEN IM=5 ELSEIF(IM2.GE.6.AND.IM2.LE.8)THEN IM=8 ELSE IM=11 ENDIF ID=WDATEDAYSINMONTH(IY,IM); EDATE=IY*10000+IM*100+ID DO I=1,2 IM=IMM; IY=IYY; ND=0 DO ND=ND+1 DO J=1,3 IF(I.EQ.2)THEN DT(ND)=DT(ND)+WDATEDAYSINMONTH(IY,IM) IF(J.EQ.1)XTXT(ND)=TRIM(ITOS(IY))//'-'//TRIM(ITOS(IM)) ENDIF IM=IM+1 IF(IM.GT.12)THEN; IM=1; IY=IY+1; ENDIF ENDDO !## current date ID=WDATEDAYSINMONTH(IY,IM); IDATE=IY*10000+IM*100+ID !## stop IF(IDATE.GT.EDATE)EXIT ENDDO !## define dt pointer IF(I.EQ.1)THEN; ALLOCATE(DT(ND),XTXT(ND)); XTXT=''; DT=0.0D0; ENDIF ENDDO WBAL_ANAYSE_PREPARE_GETHYEAR=ND END FUNCTION WBAL_ANAYSE_PREPARE_GETHYEAR !###====================================================================== INTEGER FUNCTION WBAL_ANAYSE_PREPARE_GETHSEASON(IY1,IM1,IY2,IM2,SDATE,DT,XTXT) !###====================================================================== IMPLICIT NONE INTEGER,INTENT(IN) :: IY1,IM1,IY2,IM2 INTEGER,INTENT(OUT) :: SDATE REAL(KIND=DP_KIND),INTENT(OUT),DIMENSION(:),POINTER :: DT CHARACTER(LEN=*),INTENT(OUT),DIMENSION(:),POINTER :: XTXT INTEGER :: I,J,ND,IY,IM,ID,IDATE,EDATE,IYY,IMM !## two seasons 1/04 - 30/9 !## 1/10 - 31/3 !## set start date - clipped to first of month ID=1; IY=IY1 IF(IM1.GE.4.AND.IM1.LE.9)THEN IM=4 ELSE IM=10; IF(IM1.LE.3)IY=IY-1 ENDIF SDATE=IY*10000+IM*100+ID IYY=IY IMM=IM !## set end date - rounded to end of month IY=IY2 IF(IM2.LE.9.AND.IM2.GE.4)THEN IM=9 ELSE IM=3; IF(IM2.GE.10.AND.IM2.LE.12)IY=IY+1 ENDIF ID=WDATEDAYSINMONTH(IY,IM); EDATE=IY*10000+IM*100+ID DO I=1,2 IM=IMM; IY=IYY; ND=0 DO ND=ND+1 DO J=1,6 IF(I.EQ.2)THEN DT(ND)=DT(ND)+WDATEDAYSINMONTH(IY,IM) IF(J.EQ.1)XTXT(ND)=TRIM(ITOS(IY))//'-'//TRIM(ITOS(IM)) ENDIF IM=IM+1 IF(IM.GT.12)THEN; IM=1; IY=IY+1; ENDIF ENDDO !## current date ID=WDATEDAYSINMONTH(IY,IM); IDATE=IY*10000+IM*100+ID !## stop IF(IDATE.GT.EDATE)EXIT ENDDO !## define dt pointer IF(I.EQ.1)THEN; ALLOCATE(DT(ND),XTXT(ND)); XTXT=''; DT=0.0D0; ENDIF ENDDO WBAL_ANAYSE_PREPARE_GETHSEASON=ND END FUNCTION WBAL_ANAYSE_PREPARE_GETHSEASON !###====================================================================== INTEGER FUNCTION WBAL_ANAYSE_PREPARE_GETQUARTERS(IY1,IM1,IY2,IM2,SDATE,DT,XTXT) !###====================================================================== IMPLICIT NONE INTEGER,INTENT(IN) :: IY1,IM1,IY2,IM2 INTEGER,INTENT(OUT) :: SDATE REAL(KIND=DP_KIND),INTENT(OUT),DIMENSION(:),POINTER :: DT CHARACTER(LEN=*),INTENT(OUT),DIMENSION(:),POINTER :: XTXT INTEGER :: I,J,ND,IY,IM,ID,IDATE,EDATE,IMM,IYY !## set start date - clipped to first of month ID=1; IF(IM1.LE.3)THEN IM=1 ELSEIF(IM1.LE.6)THEN IM=4 ELSEIF(IM1.LE.9)THEN IM=7 ELSE IM=10 ENDIF SDATE=IY1*10000+IM*100+ID IMM=IM IYY=IY1 !## set end date - rounded to end of month IF(IM2.LE.3)THEN IM=3 ELSEIF(IM2.LE.6)THEN IM=6 ELSEIF(IM2.LE.9)THEN IM=9 ELSE IM=12 ENDIF ID=WDATEDAYSINMONTH(IY,IM); EDATE=IY2*10000+IM*100+ID DO I=1,2 IM=IMM; IY=IYY; ND=0 DO ND=ND+1 DO J=1,3 IF(I.EQ.2)THEN DT(ND)=DT(ND)+WDATEDAYSINMONTH(IY,IM) IF(J.EQ.1)XTXT(ND)=TRIM(ITOS(IY))//'-'//TRIM(ITOS(IM)) ENDIF IM=IM+1 IF(IM.GT.12)THEN; IM=1; IY=IY+1; ENDIF ENDDO !## current date ID=WDATEDAYSINMONTH(IY,IM); IDATE=IY*10000+IM*100+ID !## stop IF(IDATE.GT.EDATE)EXIT ENDDO !## define dt pointer IF(I.EQ.1)THEN; ALLOCATE(DT(ND),XTXT(ND)); XTXT=''; DT=0.0D0; ENDIF ENDDO WBAL_ANAYSE_PREPARE_GETQUARTERS=ND END FUNCTION WBAL_ANAYSE_PREPARE_GETQUARTERS !###====================================================================== INTEGER FUNCTION WBAL_ANAYSE_PREPARE_GETDECADES(IY1,IM1,ID1,IY2,IM2,ID2,SDATE,DT,XTXT) !###====================================================================== IMPLICIT NONE INTEGER,INTENT(IN) :: IY1,IM1,ID1,IY2,IM2,ID2 INTEGER,INTENT(OUT) :: SDATE REAL(KIND=DP_KIND),INTENT(OUT),DIMENSION(:),POINTER :: DT CHARACTER(LEN=*),INTENT(OUT),DIMENSION(:),POINTER :: XTXT INTEGER :: I,ND,IY,IM,ID,IDD,JD,IDATE,EDATE !## get an approprate start date IF(ID1.LT.10)THEN ID=1 ELSEIF(ID1.LT.20)THEN ID=11 ELSE ID=21 ENDIF IDD=ID !## set start date SDATE=IY1*10000+IM1*100+ID !## get an approprate start date IF(ID2.LT.10)THEN ID=10 ELSEIF(ID2.LT.20)THEN ID=20 ELSE ID=WDATEDAYSINMONTH(IY,IM) ENDIF !## set end date EDATE=IY2*10000+IM2*100+ID DO I=1,2 IY=IY1; IM=IM1; ID=IDD; ND=0 DO JD=10; IF(ID.GT.20)JD=WDATEDAYSINMONTH(IY,IM)-20 ND=ND+1 IF(I.EQ.2)THEN DT(ND)=REAL(JD) XTXT(ND)=TRIM(ITOS(IY))//'-'//TRIM(ITOS(IM))//'-'//TRIM(ITOS(ID)) ENDIF ID=ID+JD IF(ID.GE.WDATEDAYSINMONTH(IY,IM))THEN IM=IM+1; ID=1; IF(IM.GT.12)THEN; IM=1; IY=IY+1; ENDIF ENDIF !## current date IDATE=IY*10000+IM*100+ID !## stop IF(IDATE.GT.EDATE)EXIT ENDDO !## define dt pointer IF(I.EQ.1)THEN; ALLOCATE(DT(ND),XTXT(ND)); DT=0.0D0; XTXT=''; ENDIF ENDDO WBAL_ANAYSE_PREPARE_GETDECADES=ND END FUNCTION WBAL_ANAYSE_PREPARE_GETDECADES !###====================================================================== INTEGER FUNCTION WBAL_ANAYSE_PREPARE_GETMONTHS(IY1,IM1,IY2,IM2,SDATE,DT,XTXT) !###====================================================================== IMPLICIT NONE INTEGER,INTENT(IN) :: IY1,IM1,IY2,IM2 INTEGER,INTENT(OUT) :: SDATE REAL(KIND=DP_KIND),INTENT(OUT),DIMENSION(:),POINTER :: DT CHARACTER(LEN=*),INTENT(OUT),DIMENSION(:),POINTER :: XTXT INTEGER :: NM,IM,IY,I !## get number of months IF(IY1.EQ.IY2)THEN NM=(IM2-IM1)+1 ELSE NM=(12-IM1)+1 NM= NM+12*MAX(0,(IY2-IY1-1)) NM= NM+IM2 ENDIF !## set start date of time-series SDATE=IY1*10000+IM1*100+1 !## define dt pointer ALLOCATE(DT(NM),XTXT(NM)); XTXT=''; DT=0.0D0 IM=IM1; IY=IY1 DO I=1,NM DT(I)=WDATEDAYSINMONTH(IY,IM) XTXT(I)=TRIM(ITOS(IY))//'-'//TRIM(ITOS(IM)) IM=IM+1; IF(IM.GT.12)THEN; IM=1; IY=IY+1; ENDIF ENDDO WBAL_ANAYSE_PREPARE_GETMONTHS=NM END FUNCTION WBAL_ANAYSE_PREPARE_GETMONTHS !###====================================================================== LOGICAL FUNCTION WBAL_ANALYSE_SELECT(CL,CZ,CD,IL,IZ,ID,IAG,IPOS,IDATES) !###====================================================================== IMPLICIT NONE CHARACTER(LEN=*),INTENT(IN) :: CL,CZ,CD INTEGER,INTENT(IN),DIMENSION(:) :: IDATES INTEGER,INTENT(IN) :: IAG INTEGER,INTENT(OUT) :: IL,IZ,ID,IPOS INTEGER :: IDATE WBAL_ANALYSE_SELECT=.TRUE. DO IL=1,SIZE(CMLAY) !## layer selected IF(TRIM(CMLAY(IL)).EQ.TRIM(CL))THEN DO IZ=1,SIZE(CMZONE) !## zone selected IF(TRIM(CMZONE(IZ)).EQ.TRIM(CZ))THEN DO ID=1,SIZE(CMDATE) !## date selected IF(TRIM(CMDATE(ID)).EQ.TRIM(CD))THEN SELECT CASE (IAG) !## all CASE (1:7) READ(CMDATE(ID),*) IDATE !## get location in dates DO IPOS=1,SIZE(IDATES)-1 IF(IDATE.GE.IDATES(IPOS).AND.IDATE.LT.IDATES(IPOS+1))EXIT ENDDO RETURN CASE (0,8) IPOS=ID; RETURN END SELECT ENDIF ENDDO ENDIF ENDDO ENDIF ENDDO WBAL_ANALYSE_SELECT=.FALSE. END FUNCTION WBAL_ANALYSE_SELECT !###====================================================================== LOGICAL FUNCTION WBAL_ANALYSE_TABLE() !###====================================================================== IMPLICIT NONE INTEGER :: I,NROW,N,INET INTEGER,ALLOCATABLE,DIMENSION(:) :: IC CHARACTER(LEN=52) :: CDATE WBAL_ANALYSE_TABLE=.FALSE. CALL WDIALOGSELECT(ID_DWBAL_ANALYSE_TAB3) CALL WDIALOGGETCHECKBOX(IDF_CHECK1,INET) CALL WDIALOGSELECT(ID_DWBAL_ANALYSE_TAB5) NROW=WINFOGRID(IDF_GRID1,GRIDROWSMAX) !## set number of rows N=SIZE(GRAPH(1,1)%RX) IF(N.GT.NROW)THEN CALL WMESSAGEBOX(OKONLY,EXCLAMATIONICON,COMMONOK,'iMOD can display only the first '//TRIM(ITOS(NROW))//' records of'//CHAR(13)// & 'the current set of '//TRIM(ITOS(MDATE))//' existing records in the current selection.','Warning') ENDIF ALLOCATE(IC(MBUDGET)); IC=1 CALL WGRIDCOLUMNS(IDF_GRID1,MBUDGET,IC); DEALLOCATE(IC) CALL WGRIDROWS(IDF_GRID1,N) !## set column labels DO I=1,MBUDGET IF(MOD(I,2).EQ.0)THEN IF(INET.EQ.0)CALL WGRIDLABELCOLUMN(IDF_GRID1,I,TRIM(GRAPH(I-1,1)%LEGTXT)//'_out') IF(INET.EQ.1)CALL WGRIDLABELCOLUMN(IDF_GRID1,I,'Net_'//TRIM(GRAPH(I-1,1)%LEGTXT)//'_out') ELSE IF(INET.EQ.0)CALL WGRIDLABELCOLUMN(IDF_GRID1,I,TRIM(GRAPH(I,1)%LEGTXT)//'_in') IF(INET.EQ.1)CALL WGRIDLABELCOLUMN(IDF_GRID1,I,'Net_'//TRIM(GRAPH(I,1)%LEGTXT)//'_in') ENDIF ENDDO !## set row labels DO I=1,SIZE(GRAPHDIM(1)%XTXT) !## apply axes titles predefined IF(ASSOCIATED(GRAPHDIM(1)%XTXT))THEN CDATE=GRAPHDIM(1)%XTXT(I) ELSE WRITE(CDATE,*) UTL_JDATETOIDATE(INT(GRAPH(1,1)%RX(I))) ENDIF CALL WGRIDLABELROW(IDF_GRID1,I,TRIM(CDATE)) ENDDO IF(MGROUP.EQ.1)THEN CALL WDIALOGFIELDSTATE(IDF_MENU1,2) ELSE CALL WDIALOGFIELDSTATE(IDF_MENU1,1) ENDIF CALL WDIALOGPUTMENU(IDF_MENU1,GRAPHDIM%GRAPHNAMES,MGROUP,1) CALL WBAL_ANALYSE_TABLE_FILL() CALL WDIALOGSELECT(ID_DWBAL_ANALYSE) CALL WDIALOGTABSTATE(IDF_TAB1,ID_DWBAL_ANALYSE_TAB5,1) WBAL_ANALYSE_TABLE=.TRUE. END FUNCTION WBAL_ANALYSE_TABLE !###====================================================================== SUBROUTINE WBAL_ANALYSE_TABLE_FILL() !###====================================================================== IMPLICIT NONE INTEGER :: I,IG,N CALL WDIALOGSELECT(ID_DWBAL_ANALYSE_TAB5) CALL WDIALOGGETMENU(IDF_MENU1,IG) DO I=1,MBUDGET N=SIZE(GRAPH(I,IG)%RY) CALL WGRIDPUTDOUBLE(IDF_GRID1,I,GRAPH(I,IG)%RY,N,'(F15.3)') ENDDO END SUBROUTINE WBAL_ANALYSE_TABLE_FILL !###====================================================================== LOGICAL FUNCTION WBAL_ANALYSE_EXPORTCSV(CSVFNAME) !###====================================================================== IMPLICIT NONE CHARACTER(LEN=*),INTENT(IN) :: CSVFNAME CHARACTER(LEN=256) :: FNAME CHARACTER(LEN=16) :: CDATE INTEGER :: IU,IOS,IG,I,J,INET WBAL_ANALYSE_EXPORTCSV=.FALSE. IF(LEN_TRIM(CSVFNAME).EQ.0)THEN FNAME='' IF(.NOT.UTL_WSELECTFILE('Save Comma Separated File (*.csv)|*.csv|',& SAVEDIALOG+PROMPTON+DIRCHANGE+APPENDEXT,FNAME,& 'Save Comma Separated File (*.csv)'))RETURN ELSE FNAME=CSVFNAME ENDIF CALL UTL_CREATEDIR(FNAME(:INDEX(FNAME,'\',.TRUE.)-1)) 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 CREATE file called:'//CHAR(13)//& TRIM(FNAME),'Error') RETURN ENDIF CALL WDIALOGSELECT(ID_DWBAL_ANALYSE_TAB3) CALL WDIALOGGETCHECKBOX(IDF_CHECK1,INET) DO IG=1,MGROUP WRITE(IU,'(/A)') GRAPHDIM(IG)%GRAPHNAMES WRITE(IU,'(999A)') 'Period',(','//TRIM(GRAPH(J,IG)%LEGTXT)//','//TRIM(GRAPH(J,IG)%LEGTXT),J=1,MBUDGET,2) IF(INET.EQ.0)THEN WRITE(IU,'(999A)') 'yyyymmdd',(',in,out',J=1,MBUDGET/2) ELSE WRITE(IU,'(999A)') 'yyyymmdd',(',net_in,net_out',J=1,MBUDGET/2) ENDIF DO I=1,SIZE(GRAPHDIM(1)%XTXT) !,INET+1 CDATE=GRAPHDIM(1)%XTXT(I) WRITE(IU,'(999A)') TRIM(CDATE),(','//TRIM(RTOS(GRAPH(J,IG)%RY(I),'G',7)),J=1,MBUDGET) ENDDO ENDDO CLOSE(IU) IF(LEN_TRIM(CSVFNAME).EQ.0)THEN CALL WMESSAGEBOX(OKONLY,INFORMATIONICON,COMMONOK,'Succesfully saved the current waterbalance to:'//CHAR(13)// & TRIM(FNAME),'Information') ENDIF WBAL_ANALYSE_EXPORTCSV=.TRUE. END FUNCTION WBAL_ANALYSE_EXPORTCSV !###====================================================================== LOGICAL FUNCTION WBAL_ANALYSE_EXPORTIDF() !###====================================================================== IMPLICIT NONE CHARACTER(LEN=256) :: FNAME CHARACTER(LEN=16) :: CDATE INTEGER :: I,J,K,II,JJ,IROW,ICOL,IZ,IOS CHARACTER(LEN=256) :: DIR TYPE(IDFOBJ) :: IDF WBAL_ANALYSE_EXPORTIDF=.FALSE. CALL WDIALOGSELECT(ID_DWBAL_ANALYSE_TAB4) CALL WDIALOGGETSTRING(IDF_STRING1,DIR) CALL IDFNULLIFY(IDF); CALL IDFCOPY(IDFP,IDF) !## zone numbers ALLOCATE(IPLG(NZONE)); IPLG=0 DO I=1,NZONE READ(CIZONE(I),*,IOSTAT=IOS) IPLG(I) IF(IOS.NE.0)THEN CALL WMESSAGEBOX(OKONLY,EXCLAMATIONICON,COMMONOK,'iMOD cannot convert zone '//TRIM(CIZONE(I))//CHAR(13)// & 'into a integer value.','Error') DEALLOCATE(IPLG); RETURN ENDIF ENDDO !## loop for the different periods DO I=1,SIZE(GRAPHDIM(1)%XTXT) !## loop per budget DO J=1,MBUDGET !## assign label name for each group (= zone and layer) K=0; DO II=1,NLAY IF(CLILAY(II).EQ.0)CYCLE !## reset idf file IDF%X=0.0D0 DO JJ=1,NZONE IF(CLIZONE(JJ).EQ.0)CYCLE K=K+1 !## fill in idf file DO IROW=1,IDF%NROW; DO ICOL=1,IDF%NCOL !## zone number at current location IZ=IDFP%X(ICOL,IROW) !## put water balance value onto zone IF(IPLG(JJ).EQ.IZ)IDF%X(ICOL,IROW)=GRAPH(J,K)%RY(I) ENDDO; ENDDO ENDDO !## construct filename CDATE=GRAPHDIM(1)%XTXT(I) IF(MOD(J,2).NE.0)CDATE=TRIM(CDATE)//'_in' IF(MOD(J,2).EQ.0)CDATE=TRIM(CDATE)//'_out' FNAME=TRIM(DIR)//'\'//TRIM(GRAPH(J,K)%LEGTXT)//'_'//TRIM(CDATE)//'_L'//TRIM(CILAY(II))//'.IDF' !## save idf file IF(.NOT.IDFWRITE(IDF,FNAME,1))THEN CALL WMESSAGEBOX(OKONLY,EXCLAMATIONICON,COMMONOK,'iMOD cannot SAVE file called:'//CHAR(13)//& TRIM(FNAME),'Error') CALL WBAL_ANALYSE_PLOTIMAGE_CLOSE(); RETURN ENDIF ENDDO ENDDO ENDDO CALL IDFDEALLOCATEX(IDF) CALL WBAL_ANALYSE_PLOTIMAGE_CLOSE() CALL WMESSAGEBOX(OKONLY,INFORMATIONICON,COMMONOK,'Succesfully saved the current waterbalance to IDF file(s) in:'//CHAR(13)// & TRIM(DIR),'Information') WBAL_ANALYSE_EXPORTIDF=.TRUE. END FUNCTION WBAL_ANALYSE_EXPORTIDF !###====================================================================== LOGICAL FUNCTION WBAL_ANALYSE_PLOTIMAGE(ID,IG,IGG,IP1,IP2,DIR,GTITLE,IUNIT,LSUM) !###====================================================================== IMPLICIT NONE INTEGER,PARAMETER :: NXPIX=1000, NYPIX=1200 !## resolution dx,dy INTEGER,PARAMETER :: NFLX=24 !## number of zones in current csv file CHARACTER(LEN=*),INTENT(IN) :: DIR,GTITLE INTEGER,INTENT(IN) :: ID,IG,IGG,IP1,IP2,IUNIT LOGICAL,INTENT(IN) :: LSUM REAL(KIND=DP_KIND),DIMENSION(NFLX,2) :: Q CHARACTER(LEN=10),DIMENSION(NFLX) :: QTXT REAL(KIND=DP_KIND),PARAMETER :: CS=0.0075D0 !## charactersize CHARACTER(LEN=256) :: PNGNAME,TITLE LOGICAL :: LOCAL,LPERC INTEGER :: IOS,I,II,J,IBITMAP,IWINDOW,I1,I2,IB,IT,NCF,IZ CHARACTER(LEN=4) :: STRUNIT INTEGER :: SUMNR DATA QTXT/'Q-drn ','Q-olf ','Q-riv ','Q-ghb ','Q-isg ', & 'Q-wel ','Q-reg ','Q-cnh ','Q-ftf ','Q-flf ', & 'Q-rch ','Q-evt ','Q-cap ','Q-etact ','Q-pm ', & 'Q-pmgw ','Q-pmsw ','Q-sto ','Q-decsto','Q-spgw ', & 'Q-cor ','Q-qdr ','Q-qrun ','Q-modf '/ WBAL_ANALYSE_PLOTIMAGE=.FALSE. !## zone numbers ALLOCATE(IPLG(NZONE)); IPLG=0 DO I=1,NZONE READ(CIZONE(I),*,IOSTAT=IOS) IPLG(I) IF(IOS.NE.0)THEN CALL WMESSAGEBOX(OKONLY,EXCLAMATIONICON,COMMONOK,'iMOD cannot convert zone '//TRIM(CIZONE(I))//CHAR(13)// & 'into a integer value.','Error') DEALLOCATE(IPLG); RETURN ENDIF ENDDO !## allocate qsubregio for all zones ALLOCATE(QSUBREGIO(NZONE,2)) !## polygon selected DO II=1,2 NCF=0; DO I=1,NZONE IF(LIZONE(I).EQ.1)THEN NCF=NCF+1; IF(II.EQ.2)IPOL(NCF)=I ENDIF ENDDO IF(II.EQ.1)ALLOCATE(IPOL(NCF)) ENDDO !## generate image for all timeseries (if available) ITLOOP: DO IT=1,SIZE(GRAPH(1,1)%RY) !## initialise values Q=0.0D0 I1=-1; I2=0; I=0 DO IB=1,MBUDGET,2 I=I+1 I1=I1+2; I2=I2+2 !## get appropriate balancenumber J=WBAL_ANALYSE_GETQCATEGORY(GRAPH(I1,IG)%CTYPE) !## connected flow - need to saved further IF(J.EQ.-1)CYCLE !## cannot get right number IF(J.EQ.0)THEN CALL WMESSAGEBOX(OKONLY,EXCLAMATIONICON,COMMONOK,'iMOD cannot find category for '//TRIM(BUDGET(I)%FLUXTERM),'Error'); EXIT ITLOOP ENDIF !## sum volumes positive/negative separately Q(J,1)=Q(J,1)+GRAPH(I1,IG)%RY(IT) Q(J,2)=Q(J,2)+GRAPH(I2,IG)%RY(IT) ENDDO !## initialise values QSUBREGIO=0.0D0 !## get regio fluxes I1=-1; I2=0; I=0 DO IB=1,MBUDGET,2 I1=I1+2; I2=I2+2; I=I+1 !## get appropriate polygon numbers that are currently selected J=WBAL_ANALYSE_GETQCATEGORY(GRAPH(I1,IG)%CTYPE) IF(J.NE.-1)CYCLE !## get zone number READ(GRAPH(I1,IG)%CTYPE,'(6X,I7)') IZ !## find appropriate zone in list DO I=1,NZONE; IF(IPLG(I).EQ.IZ)EXIT; ENDDO !## skip this one IF(I.GT.NZONE)THEN CALL WMESSAGEBOX(OKONLY,EXCLAMATIONICON,COMMONOK,'Cannot find the polygon number from '//TRIM(GRAPH(I1,IG)%CTYPE),'Error'); EXIT ITLOOP ENDIF NCF=I QSUBREGIO(NCF,1)=GRAPH(I1,IG)%RY(IT) QSUBREGIO(NCF,2)=GRAPH(I2,IG)%RY(IT) ENDDO !! Q(01,1)=QDRN_IN Q(01,1)=QDRN_OUT Q(13,1)=QCAP_IN Q(13,1)=QCAP_OUT !! Q(02,1)=QOLF_IN Q(02,1)=QOLF_OUT Q(14,1)=QETACT_IN Q(14,1)=QETACT_OUT !! Q(03,1)=QRIV_IN Q(03,1)=QRIV_OUT Q(15,1)=QPM_IN Q(15,1)=QPM_OUT !! Q(04,1)=QGHB_IN Q(04,1)=QGHB_OUT Q(16,1)=QPMGW_IN Q(16,1)=QPMGW_OUT !! Q(05,1)=QISG_IN Q(05,1)=QISG_OUT Q(17,1)=QPMSW_IN Q(17,1)=QPMSW_OUT !! Q(06,1)=QWEL_IN Q(06,1)=QWEL_OUT Q(18,1)=QSTO_IN Q(18,1)=QSTO_OUT !! Q(07,1)=QREG_IN Q(07,1)=QREG_OUT Q(19,1)=QDECSTO_INQ(19,1)=QDECSTO_OUT !! Q(08,1)=QCNH_IN Q(08,1)=QCNH_OUT Q(20,1)=QQSPGW_IN Q(20,1)=QQSPGW_OUT !! Q(09,1)=QFLF1_IN Q(09,1)=QFLF1_OUT Q(21,1)=QQCOR_IN Q(21,1)=QQCOR_OUT !! Q(10,1)=QFLF2_IN Q(10,1)=QFLF2_OUT Q(22,1)=QQDR_IN Q(22,1)=QQDR_OUT !! Q(11,1)=QRCH_IN Q(11,1)=QRCH_OUT Q(23,1)=QQRUN_IN Q(23,1)=QQRUN_OUT !! Q(12,1)=QEVT_IN Q(12,1)=QEVT_OUT Q(24,1)=QMODF_IN Q(24,1)=QMODF_OUT !## plot local window of selected polygon ipol LOCAL=.FALSE.; IF(IP1.EQ.1)LOCAL=.TRUE. !## percentiles LPERC=.FALSE.; IF(IP2.EQ.1)LPERC=.TRUE. IF(LPERC)THEN STRUNIT='% ' ELSE IF(IUNIT.EQ.1)THEN STRUNIT='m3/d' ELSE STRUNIT='mm/d' ENDIF ENDIF !## zone number absent in case of zone summing SUMNR=0 !## not summed zones - get current polygon IF(.NOT.LSUM)SUMNR=IPLG(IPOL(IGG)) !## id is for preview or save TITLE=GTITLE IF(INDEX(GTITLE,'$').GT.0)TITLE=UTL_SUBST(GTITLE,'$','('//TRIM(GRAPHDIM(1)%XTXT(IT))//';'//TRIM(GRAPHDIM(IG)%GRAPHNAMES)//')') IF(.NOT.DRAWBAL(Q,QTXT,NXPIX,NYPIX,CS,IPOL,SIZE(LIZONE),QSUBREGIO,CLRIZONE,IPLG,IDFP,LOCAL,TITLE,IBITMAP,LSUM,STRUNIT,SUMNR))EXIT ITLOOP !## display image in viewer IF(ID.EQ.ID_PREVIEW)THEN CALL WINDOWOPENCHILD(IWINDOW,FLAGS=SYSMENUON+FIXEDSIZEWIN+HIDEWINDOW,TITLE='VIEWING: '//TRIM(PNGNAME)) CALL IGRSELECT(DRAWWIN) CALL WBITMAPVIEW(IBITMAP,0,0,MODAL,KEYSCROLL+DRAGSCROLL) CALL WBITMAPDESTROY(IBITMAP) ELSE PNGNAME=TRIM(GRAPHDIM(1)%XTXT(IT))//'_'//TRIM(GRAPHDIM(IG)%GRAPHNAMES) DO I=INDEX(TRIM(PNGNAME),';'); IF(I.EQ.0)EXIT PNGNAME(I:I)='_' ENDDO DO I=INDEX(TRIM(PNGNAME),' '); IF(I.EQ.0)EXIT PNGNAME(I:I)='_' ENDDO DO IF(INDEX(TRIM(PNGNAME),'__').EQ.0)EXIT PNGNAME=UTL_SUBST(TRIM(PNGNAME),'__','_') ENDDO PNGNAME=TRIM(DIR)//'\'//TRIM(PNGNAME)//'.PNG' I=INFOERROR(1) CALL WBITMAPSAVE(IBITMAP,PNGNAME) I=INFOERROR(1) CALL WBITMAPDESTROY(IBITMAP) IF(I.NE.0)THEN CALL WMESSAGEBOX(OKONLY,EXCLAMATIONICON,COMMONOK,'iMOD cannot SAVE the requested bitmap file called:'//CHAR(13)//& TRIM(PNGNAME),'Error') EXIT ITLOOP ENDIF ENDIF ENDDO ITLOOP CALL WBAL_ANALYSE_PLOTIMAGE_CLOSE() IF(IT.GT.SIZE(GRAPH(1,1)%RY))WBAL_ANALYSE_PLOTIMAGE=.TRUE. END FUNCTION WBAL_ANALYSE_PLOTIMAGE !###====================================================================== SUBROUTINE WBAL_ANALYSE_PLOTIMAGE_CLOSE() !###====================================================================== IMPLICIT NONE IF(ALLOCATED(IPOL)) DEALLOCATE(IPOL) IF(ALLOCATED(QSUBREGIO))DEALLOCATE(QSUBREGIO) IF(ALLOCATED(IPLG)) DEALLOCATE(IPLG) END SUBROUTINE WBAL_ANALYSE_PLOTIMAGE_CLOSE !###====================================================================== SUBROUTINE WBAL_ANALYSE_INIT(FNAME,IBATCH) !###====================================================================== IMPLICIT NONE INTEGER,INTENT(IN) :: IBATCH CHARACTER(LEN=*),INTENT(IN) :: FNAME IF(IBATCH.EQ.0)THEN CALL WINDOWSELECT(0) IF(WMENUGETSTATE(ID_WBAL_ANALYSE,2).EQ.1)THEN CALL WBAL_ANALYSE_CLOSE() RETURN ENDIF CALL MAIN_UTL_INACTMODULE(ID_WBAL_ANALYSE) !## other module no closed, no approvement given IF(IDIAGERROR.EQ.1)RETURN CALL WMENUSETSTATE(ID_WBAL_ANALYSE,2,1) ENDIF !## fill in dialog CALL WDIALOGLOAD(ID_DWBAL_ANALYSE,ID_DWBAL_ANALYSE) CALL WDIALOGSELECT(ID_DWBAL_ANALYSE_TAB1) CALL WDIALOGPUTIMAGE(ID_OPEN1,ID_ICONOPEN,1) CALL WDIALOGPUTIMAGE(ID_OPEN2,ID_ICONOPEN,1) CALL WDIALOGSELECT(ID_DWBAL_ANALYSE_TAB2) CALL WDIALOGPUTIMAGE(ID_PLUS1,ID_ICONPLUS,1) CALL WDIALOGPUTIMAGE(ID_PLUS2,ID_ICONPLUS,1) CALL WDIALOGPUTIMAGE(ID_MIN1,ID_ICONMIN,1) CALL WDIALOGPUTIMAGE(ID_MIN2,ID_ICONMIN,1) CALL WDIALOGSELECT(ID_DWBAL_ANALYSE_TAB3) CALL WDIALOGPUTIMAGE(ID_PLUS1,ID_ICONPLUS,1) CALL WDIALOGPUTIMAGE(ID_PLUS2,ID_ICONPLUS,1) CALL WDIALOGPUTIMAGE(ID_MIN1,ID_ICONMIN,1) CALL WDIALOGPUTIMAGE(ID_MIN2,ID_ICONMIN,1) CALL WDIALOGSELECT(ID_DWBAL_ANALYSE_TAB4) CALL WDIALOGPUTIMAGE(ID_OPEN1,ID_ICONOPEN,1) CALL WDIALOGPUTSTRING(IDF_STRING2,'Figure Text, use $ in the string to include at that position details of aggregation between brackets.') CALL WDIALOGPUTSTRING(IDF_STRING1,TRIM(PREFVAL(1))//'\tmp') CALL WDIALOGFIELDSTATE(IDF_STRING1,2) !## outgrey tabs CALL WDIALOGSELECT(ID_DWBAL_ANALYSE) CALL WDIALOGTABSTATE(IDF_TAB1,ID_DWBAL_ANALYSE_TAB2,0) CALL WDIALOGTABSTATE(IDF_TAB1,ID_DWBAL_ANALYSE_TAB3,0) CALL WDIALOGTABSTATE(IDF_TAB1,ID_DWBAL_ANALYSE_TAB4,0) CALL WDIALOGTABSTATE(IDF_TAB1,ID_DWBAL_ANALYSE_TAB5,0) IF(LEN_TRIM(FNAME).GT.0)THEN IF(WBAL_ANALYSE_READCSV(FNAME))THEN CALL WBAL_ANALYSE_TAB3_FIELD() CALL WDIALOGSELECT(ID_DWBAL_ANALYSE) IF(IBATCH.EQ.0)CALL UTL_DIALOGSHOW(-1,-1,0,2) ELSE CALL WDIALOGUNLOAD() ENDIF ELSE CALL WDIALOGSELECT(ID_DWBAL_ANALYSE) IF(IBATCH.EQ.0)CALL UTL_DIALOGSHOW(-1,-1,0,2) ENDIF END SUBROUTINE WBAL_ANALYSE_INIT !###====================================================================== SUBROUTINE WBAL_ANALYSE_DEALLOCATE() !###====================================================================== IMPLICIT NONE INTEGER :: I IF(ALLOCATED(GWBAL))THEN DO I=1,SIZE(GWBAL) IF(ASSOCIATED(GWBAL(I)%CDATE))DEALLOCATE(GWBAL(I)%CDATE) IF(ASSOCIATED(GWBAL(I)%CLAY)) DEALLOCATE(GWBAL(I)%CLAY) IF(ASSOCIATED(GWBAL(I)%AREA)) DEALLOCATE(GWBAL(I)%AREA) IF(ASSOCIATED(GWBAL(I)%CZONE))DEALLOCATE(GWBAL(I)%CZONE) IF(ASSOCIATED(GWBAL(I)%Q)) DEALLOCATE(GWBAL(I)%Q) IF(ASSOCIATED(GWBAL(I)%TXT)) DEALLOCATE(GWBAL(I)%TXT) ENDDO DEALLOCATE(GWBAL) ENDIF IF(ALLOCATED(BUDGET))DEALLOCATE(BUDGET) IF(ALLOCATED(CILAY)) DEALLOCATE(CILAY) IF(ALLOCATED(CIZONE)) DEALLOCATE(CIZONE) IF(ALLOCATED(CIDATE)) DEALLOCATE(CIDATE) IF(ALLOCATED(LILAY)) DEALLOCATE(LILAY) IF(ALLOCATED(LIZONE)) DEALLOCATE(LIZONE) IF(ALLOCATED(CLRIZONE))DEALLOCATE(CLRIZONE) IF(ALLOCATED(LIDATE)) DEALLOCATE(LIDATE) ! IF(ALLOCATED(SQ)) DEALLOCATE(SQ) ! IF(ALLOCATED(UQ)) DEALLOCATE(UQ) ! IF(ALLOCATED(OSQ)) DEALLOCATE(OSQ) IF(ALLOCATED(CLILAY)) DEALLOCATE(CLILAY) IF(ALLOCATED(CLIZONE)) DEALLOCATE(CLIZONE) CALL IDFDEALLOCATEX(IDFP) END SUBROUTINE WBAL_ANALYSE_DEALLOCATE !###====================================================================== SUBROUTINE WBAL_ANALYSE_CLOSE() !###====================================================================== IMPLICIT NONE CALL WINDOWSELECT(0) CALL WMENUSETSTATE(ID_WBAL_ANALYSE,2,0) CALL GRAPH_DEALLOCATE() CALL WBAL_ANALYSE_DEALLOCATE() CALL WDIALOGSELECT(ID_DWBAL_ANALYSE) CALL WDIALOGUNLOAD() END SUBROUTINE WBAL_ANALYSE_CLOSE END MODULE MOD_WBAL_ANALYSE