!! 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_GEOCONNECT_PAR USE WINTERACTER USE RESOURCE USE MODPLOT USE MOD_UTL, ONLY : UTL_READINITFILE,UTL_GETUNIT,ITOS,RTOS,UTL_IDFSNAPTOGRID,UTL_CAP,UTL_DIRINFO_POINTER USE MOD_IDF_PAR, ONLY : IDFOBJ USE MOD_IDF, ONLY : IDFNULLIFY,IDFCOPY,IDFDEALLOCATE,IDFDEALLOCATEX USE MOD_OSD, ONLY : OSD_OPEN !## IDF-types to read IDF-files from given folders TYPE(IDFOBJ),ALLOCATABLE,DIMENSION(:),SAVE :: TOPM,BOTM,CIDF,KDHIDF,KDVIDF,KHVIDF,KVAIDF,KVVIDF,RESM !## IDF-types for REGIS-files TYPE(IDFOBJ),SAVE :: TOPR,BOTR,KHR,KVR,IDF,TOP,BOT,THK !## store available filenames CHARACTER(LEN=256),DIMENSION(:),POINTER :: REGISFILES INTEGER,ALLOCATABLE,DIMENSION(:) :: IACTM INTEGER,SAVE :: NLAYM, & !## NLAYM (model), NLAYR, & !## NLAYR (Regis) IAGGR, & !## aggregate number (1,2, or 3) IWINDOW, & !## window specified MODELTYPE, & !## type of model results to aggregate INPUTTYPE, & !## type of input to aggregate IAGGR_TYPE, & !## expression to aggregate (1,2,3,4) IOPTW, & ISAVETB !## save top/bottom after aggregation CHARACTER(LEN=256),SAVE :: OUTPUTFOLDER,DBASEFOLDER,MODELFOLDER,REGISFOLDER,TOPFOLDER,BOTFOLDER,IPEST,IPFFILE !## IFLAG related to GC computation options 1=identify, 2=preprocessing, 3=postprocessing INTEGER :: GC_IFLAG,ISAVEK,ISAVEC LOGICAL :: IDENTIFY_PIPET TYPE FRMOBJ CHARACTER(LEN=12) :: FORM CHARACTER(LEN=1) :: LITHO REAL(KIND=DP_KIND) :: FACT INTEGER :: IGRP,LITHOCLR REAL(KIND=DP_KIND),POINTER,DIMENSION(:) :: FVAL=>NULL() END TYPE TYPE(FRMOBJ),ALLOCATABLE,DIMENSION(:) :: IPFAC CONTAINS !###====================================================================== LOGICAL FUNCTION GC_ALLOCATE() !###====================================================================== IMPLICIT NONE INTEGER :: I,IOS GC_ALLOCATE=.FALSE. !## clean memory first CALL GC_DEALLOCATE() !## try to allocate all memory ALLOCATE(CIDF(NLAYM-1),KDHIDF(NLAYM),KDVIDF(NLAYM),TOPM(NLAYM), & BOTM(NLAYM) ,KHVIDF(NLAYM),KVAIDF(NLAYM),KVVIDF(NLAYM-1), & IACTM(NLAYM) ,RESM(NLAYM),STAT=IOS) IF(IOS.NE.0)THEN CALL WMESSAGEBOX(OKONLY,EXCLAMATIONICON,COMMONOK,'iMOD cannot allocate neccessary memory.','Error') RETURN ENDIF !## nullify idf-objects DO I=1,SIZE(CIDF); CALL IDFNULLIFY(CIDF(I)); ENDDO DO I=1,SIZE(KDHIDF); CALL IDFNULLIFY(KDHIDF(I)); ENDDO DO I=1,SIZE(KDVIDF); CALL IDFNULLIFY(KDVIDF(I)); ENDDO DO I=1,SIZE(KHVIDF); CALL IDFNULLIFY(KHVIDF(I)); ENDDO DO I=1,SIZE(KVVIDF); CALL IDFNULLIFY(KVVIDF(I)); ENDDO DO I=1,SIZE(KVAIDF); CALL IDFNULLIFY(KVAIDF(I)); ENDDO CALL IDFNULLIFY(KHR); CALL IDFNULLIFY(KVR) CALL IDFNULLIFY(TOPR); CALL IDFNULLIFY(BOTR) DO I=1,SIZE(RESM); CALL IDFNULLIFY(RESM(I)); ENDDO GC_ALLOCATE=.TRUE. END FUNCTION GC_ALLOCATE !###====================================================================== SUBROUTINE GC_DEALLOCATE() !###====================================================================== IMPLICIT NONE !## deallocate all arrays IF(ALLOCATED(IACTM))DEALLOCATE(IACTM) IF(ALLOCATED(TOPM))THEN; CALL IDFDEALLOCATE(TOPM,SIZE(TOPM)); DEALLOCATE(TOPM); ENDIF IF(ALLOCATED(BOTM))THEN; CALL IDFDEALLOCATE(BOTM,SIZE(BOTM)); DEALLOCATE(BOTM); ENDIF IF(ALLOCATED(RESM))THEN; CALL IDFDEALLOCATE(RESM,SIZE(RESM)); DEALLOCATE(RESM); ENDIF IF(ALLOCATED(CIDF))THEN; CALL IDFDEALLOCATE(CIDF,SIZE(CIDF)); DEALLOCATE(CIDF); ENDIF IF(ALLOCATED(KDHIDF))THEN; CALL IDFDEALLOCATE(KDHIDF,SIZE(KDHIDF)); DEALLOCATE(KDHIDF); ENDIF IF(ALLOCATED(KDVIDF))THEN; CALL IDFDEALLOCATE(KDVIDF,SIZE(KDVIDF)); DEALLOCATE(KDVIDF); ENDIF IF(ALLOCATED(KHVIDF))THEN; CALL IDFDEALLOCATE(KHVIDF,SIZE(KHVIDF)); DEALLOCATE(KHVIDF); ENDIF IF(ALLOCATED(KVAIDF))THEN; CALL IDFDEALLOCATE(KVAIDF,SIZE(KVAIDF)); DEALLOCATE(KVAIDF); ENDIF IF(ALLOCATED(KVVIDF))THEN; CALL IDFDEALLOCATE(KVVIDF,SIZE(KVVIDF)); DEALLOCATE(KVVIDF); ENDIF CALL IDFDEALLOCATEX(KHR); CALL IDFDEALLOCATEX(KVR) CALL IDFDEALLOCATEX(TOPR); CALL IDFDEALLOCATEX(BOTR) CALL IDFDEALLOCATEX(IDF); CALL IDFDEALLOCATEX(TOP) CALL IDFDEALLOCATEX(BOT); CALL IDFDEALLOCATEX(THK) END SUBROUTINE GC_DEALLOCATE !###====================================================================== LOGICAL FUNCTION GC_INIT_READ(JU,FNAME,IMODBATCH) !###====================================================================== IMPLICIT NONE INTEGER,INTENT(IN) :: JU,IMODBATCH CHARACTER(LEN=*),INTENT(IN) :: FNAME INTEGER :: IU,I,IOS CHARACTER(LEN=256) :: LINE GC_INIT_READ=.FALSE. !## read *.txt-file IF(JU.EQ.0)THEN IU=UTL_GETUNIT(); CALL OSD_OPEN(IU,FILE=TRIM(FNAME),STATUS='OLD',FORM='FORMATTED',ACTION='READ',IOSTAT=IOS) IF(IOS.NE.0)RETURN ELSE IU=JU ENDIF IF(.NOT.UTL_READINITFILE('NLAY',LINE,IU,0))RETURN READ(LINE,*) NLAYM; IF(IMODBATCH.EQ.1)WRITE(*,'(A,I3)') 'NLAY=',NLAYM !## allocate arrays IF(.NOT.GC_ALLOCATE())RETURN IF(.NOT.UTL_READINITFILE('REGISFOLDER',LINE,IU,0))RETURN READ(LINE,*) REGISFOLDER; IF(IMODBATCH.EQ.1)WRITE(*,'(A)') 'REGISFOLDER='//TRIM(REGISFOLDER) IF(.NOT.UTL_READINITFILE('TOPFOLDER',LINE,IU,0))RETURN READ(LINE,*) TOPFOLDER; IF(IMODBATCH.EQ.1)WRITE(*,'(A)') 'TOPFOLDER='//TRIM(TOPFOLDER) IF(.NOT.UTL_READINITFILE('BOTFOLDER',LINE,IU,0))RETURN READ(LINE,*) BOTFOLDER; IF(IMODBATCH.EQ.1)WRITE(*,'(A)') 'BOTFOLDER='//TRIM(BOTFOLDER) !## on default all layers are activated IACTM=1; IF(UTL_READINITFILE('ACTLAYERS',LINE,IU,1))READ(LINE,'(99I1)') (IACTM(I),I=1,NLAYM) IF(IMODBATCH.EQ.1)WRITE(*,'(A,99I1)') 'ACTLAYERS=',IACTM GC_INIT_READ=.TRUE. IF(JU.EQ.0)CLOSE(IU) END FUNCTION GC_INIT_READ !###====================================================================== SUBROUTINE GC_INIT_WRITE(JU,FNAME) !###====================================================================== IMPLICIT NONE INTEGER,INTENT(IN) :: JU CHARACTER(LEN=*),INTENT(IN) :: FNAME INTEGER :: I,IU,IOS IF(JU.EQ.0)THEN IU=UTL_GETUNIT() CALL OSD_OPEN(IU,FILE=TRIM(FNAME),STATUS='UNKNOWN',FORM='FORMATTED',ACTION='WRITE,DENYREAD',IOSTAT=IOS) IF(IOS.NE.0)RETURN ELSE IU=JU ENDIF WRITE(IU,'(A5,I3)') 'NLAY=',NLAYM WRITE(IU,'(A10,99I1)') 'ACTLAYERS=',(IACTM(I),I=1,NLAYM) WRITE(IU,'(A)') 'REGISFOLDER='//TRIM(REGISFOLDER) WRITE(IU,'(A)') 'TOPFOLDER='//TRIM(TOPFOLDER) WRITE(IU,'(A)') 'BOTFOLDER='//TRIM(BOTFOLDER) IF(JU.EQ.0)CLOSE(IU) END SUBROUTINE GC_INIT_WRITE !###====================================================================== SUBROUTINE GC_INIT_GET() !###====================================================================== IMPLICIT NONE INTEGER :: I CALL WDIALOGSELECT(ID_DGEOCONNECT_TAB4) !## get amount of model layers CALL WDIALOGGETINTEGER(IDF_INTEGER1,NLAYM) !## get directory of REGIS files CALL WDIALOGGETSTRING(IDF_STRING1,REGISFOLDER) !## get directory of TOP files model CALL WDIALOGGETSTRING(IDF_STRING2,TOPFOLDER) !## get directory of BOT files model CALL WDIALOGGETSTRING(IDF_STRING3,BOTFOLDER) !## read formation name from grid DO I=1,SIZE(IACTM) CALL WGRIDGETCELLCHECKBOX(IDF_GRID1,1,I,IACTM(I)) ENDDO END SUBROUTINE GC_INIT_GET !###====================================================================== SUBROUTINE GC_INIT_PUT() !###====================================================================== IMPLICIT NONE INTEGER :: I CALL WDIALOGSELECT(ID_DGEOCONNECT_TAB4) !## get amount of model layers CALL WDIALOGPUTINTEGER(IDF_INTEGER1,NLAYM) CALL WDIALOGFIELDSTATE(IDF_INTEGER1,2) !## get directory of REGIS files CALL WDIALOGPUTSTRING(IDF_STRING1,REGISFOLDER) !## get directory of TOP files model CALL WDIALOGPUTSTRING(IDF_STRING2,TOPFOLDER) !## get directory of BOT files model CALL WDIALOGPUTSTRING(IDF_STRING3,BOTFOLDER) !## read formation name from grid CALL WGRIDROWS(IDF_GRID1,NLAYM) DO I=1,SIZE(IACTM) CALL WGRIDLABELROW(IDF_GRID1,I,'Layer '//TRIM(ITOS(I))) CALL WGRIDPUTCELLCHECKBOX(IDF_GRID1,1,I,IACTM(I)) ENDDO !## call to routine that 1. reads REGIS files, 2. fills IPFAC%FORM with Regis formation names, CALL WDIALOGSELECT(ID_DGEOCONNECT_TAB2) IF(.NOT.GC_REGISFILES_GETLIST())RETURN IF(.NOT.GC_REGISFILES_PUT(ID_DGEOCONNECT_TAB2))RETURN IF(.NOT.GC_REGISFILES_PUT(ID_DGEOCONNECT_TAB3))RETURN END SUBROUTINE GC_INIT_PUT !###====================================================================== SUBROUTINE GC_INIT_PREPROCESSING_WRITE(FNAME) !###====================================================================== IMPLICIT NONE INTEGER :: IU,IOS,I CHARACTER(LEN=256),INTENT(IN) :: FNAME CHARACTER(LEN=256) :: LINE IU=UTL_GETUNIT() CALL OSD_OPEN(IU,FILE=FNAME,STATUS='UNKNOWN',FORM='FORMATTED',ACTION='WRITE,DENYREAD',IOSTAT=IOS) IF(IOS.NE.0)RETURN WRITE(IU,'(A)') 'FUNCTION=GEOCONNECT' !## write common settings CALL GC_INIT_WRITE(IU,'') WRITE(IU,'(A6,I1)') 'IFLAG=',GC_IFLAG IF(IWINDOW.EQ.2)THEN WRITE(IU,'(A7,4(F10.2,1X))') 'WINDOW=',IDF%XMIN,IDF%XMAX,IDF%YMIN,IDF%YMAX WRITE(IU,'(A,F10.2)') 'CELLSIZE=',IDF%DX ENDIF WRITE(IU,'(A,I10)') 'NFORM=',SIZE(IPFAC%FORM) DO I=1,SIZE(IPFAC%FORM) LINE='FORM'//TRIM(ITOS(I))//'='//TRIM(IPFAC(I)%FORM)//','//TRIM(RTOS(IPFAC(I)%FACT,'F',3)) WRITE(IU,'(A)') TRIM(LINE) ENDDO WRITE(IU,'(A)') 'OUTPUTFOLDER='//TRIM(OUTPUTFOLDER) WRITE(IU,'(A,I1)') 'ISAVEK=',ISAVEK WRITE(IU,'(A,I1)') 'ISAVEC=',ISAVEC CLOSE(IU) END SUBROUTINE GC_INIT_PREPROCESSING_WRITE !###====================================================================== LOGICAL FUNCTION GC_INIT_PREPROCESSING_READ(IU,IMODBATCH) !###====================================================================== IMPLICIT NONE INTEGER,INTENT(IN) :: IU,IMODBATCH INTEGER :: I,J,N REAL(KIND=DP_KIND) :: FACT CHARACTER(LEN=256) :: LINE CHARACTER(LEN=52) :: FORM GC_INIT_PREPROCESSING_READ=.FALSE. IF(.NOT.UTL_READINITFILE('IFLAG',LINE,IU,0))RETURN READ(LINE,*) GC_IFLAG; WRITE(*,'(A,I2)') 'IFLAG=',GC_IFLAG IF(GC_IFLAG.NE.2)THEN CALL WMESSAGEBOX(OKONLY,EXCLAMATIONICON,COMMONOK,'The chosen INI file is not meant to be read in for the PRE-processing tab.','Error') ENDIF OUTPUTFOLDER='' IWINDOW=1 !## read common settings IF(.NOT.GC_INIT_READ(IU,'',IMODBATCH))RETURN !## put settings on tab4 IF(IMODBATCH.EQ.0)CALL GC_INIT_PUT() IF(UTL_READINITFILE('WINDOW',LINE,IU,1))THEN IWINDOW=2; READ(LINE,*) IDF%XMIN,IDF%YMIN,IDF%XMAX,IDF%YMAX IF(IMODBATCH.EQ.1)WRITE(*,'(A,4(F10.3,1X))') 'WINDOW=',IDF%XMIN,IDF%YMIN,IDF%XMAX,IDF%YMAX IF(.NOT.UTL_READINITFILE('CELLSIZE',LINE,IU,0))RETURN READ(LINE,*) IDF%DX; IDF%DY=IDF%DX IF(IMODBATCH.EQ.1)WRITE(*,'(A,F10.3)') 'CELLSIZE=',IDF%DX IF(IDF%DX.LE.0.0D0)THEN CALL WMESSAGEBOX(OKONLY,EXCLAMATIONICON,COMMONOK,'You should specify a CellSize of greater than 0.0D0.','Error') RETURN ENDIF ENDIF IF(IWINDOW.EQ.1)THEN IDF%NCOL=0; IDF%NROW=0 ELSE CALL UTL_IDFSNAPTOGRID(IDF%XMIN,IDF%XMAX,IDF%YMIN,IDF%YMAX,IDF%DX,IDF%NCOL,IDF%NROW) ENDIF IF(.NOT.UTL_READINITFILE('NFORM',LINE,IU,0))RETURN READ(LINE,*) N; IF(IMODBATCH.EQ.1)WRITE(*,'(A,I10)') 'NFORM=',N !## check consistency with current geoconnect settings IF(IMODBATCH.EQ.0)THEN IF(N.NE.NLAYR)THEN CALL WMESSAGEBOX(OKONLY,EXCLAMATIONICON,COMMONOK,'The current ini file does not match with your current GeoConnect settings'//CHAR(13)// & 'iMOD found too many geological formation compared to the current ones loading in the GeoConnect Tool','Error') RETURN ENDIF ELSE NLAYR=N !## started from imodbatch - allocate memory ALLOCATE(IPFAC(NLAYR)) ENDIF DO I=1,NLAYR IF(.NOT.UTL_READINITFILE('FORM'//TRIM(ITOS(I)),LINE,IU,0))RETURN READ(LINE,*) FORM,FACT !## make sure to connect with correct formation IF(IMODBATCH.EQ.0)THEN FORM=UTL_CAP(FORM,'U') DO J=1,NLAYR IF(TRIM(FORM).EQ.TRIM(UTL_CAP(IPFAC(J)%FORM,'U')))THEN; IPFAC(J)%FACT=FACT; EXIT; ENDIF ENDDO IF(J.GT.NLAYR)THEN CALL WMESSAGEBOX(OKONLY,EXCLAMATIONICON,COMMONOK,'iMOD cannot find '//TRIM(FORM),'Error') RETURN ENDIF ELSE IPFAC(I)%FORM=FORM; IPFAC(I)%FACT=FACT ENDIF LINE='FORM'//TRIM(ITOS(I))//'='//TRIM(IPFAC(I)%FORM)//','//TRIM(RTOS(IPFAC(I)%FACT,'F',3)) IF(IMODBATCH.EQ.1)WRITE(*,'(A)') TRIM(LINE) ENDDO IF(.NOT.UTL_READINITFILE('ISAVEK',LINE,IU,0))RETURN READ(LINE,*) ISAVEK; IF(IMODBATCH.EQ.1)WRITE(*,'(A7,I1)') 'ISAVEK=',ISAVEK IF(.NOT.UTL_READINITFILE('ISAVEC',LINE,IU,0))RETURN READ(LINE,*) ISAVEC; IF(IMODBATCH.EQ.1)WRITE(*,'(A7,I1)') 'ISAVEC=',ISAVEC IF(.NOT.UTL_READINITFILE('OUTPUTFOLDER',LINE,IU,0))RETURN READ(LINE,*) OUTPUTFOLDER; IF(IMODBATCH.EQ.1)WRITE(*,'(A)') 'OUTPUTFOLDER='//TRIM(OUTPUTFOLDER) GC_INIT_PREPROCESSING_READ=.TRUE. END FUNCTION GC_INIT_PREPROCESSING_READ !###====================================================================== SUBROUTINE GC_INIT_PREPROCESSING_PUT() !###====================================================================== IMPLICIT NONE INTEGER :: I CALL WDIALOGSELECT(ID_DGEOCONNECT_TAB2) !## get window IF(IWINDOW.EQ.1)THEN CALL WDIALOGPUTRADIOBUTTON(IDF_RADIO1) CALL WDIALOGPUTDOUBLE(IDF_REAL1,MPW%XMIN,'(F15.3)'); CALL WDIALOGPUTDOUBLE(IDF_REAL2,MPW%YMIN,'(F15.3)') CALL WDIALOGPUTDOUBLE(IDF_REAL3,MPW%XMAX,'(F15.3)'); CALL WDIALOGPUTDOUBLE(IDF_REAL4,MPW%YMAX,'(F15.3)') CALL WDIALOGPUTDOUBLE(IDF_REAL5,100.0D0,'(F15.3)') ELSEIF(IWINDOW.EQ.2)THEN CALL WDIALOGPUTRADIOBUTTON(IDF_RADIO2) CALL WDIALOGPUTDOUBLE(IDF_REAL1,IDF%XMIN,'(F15.3)'); CALL WDIALOGPUTDOUBLE(IDF_REAL2,IDF%YMIN,'(F15.3)') CALL WDIALOGPUTDOUBLE(IDF_REAL3,IDF%XMAX,'(F15.3)'); CALL WDIALOGPUTDOUBLE(IDF_REAL4,IDF%YMAX,'(F15.3)') CALL WDIALOGPUTDOUBLE(IDF_REAL5,IDF%DX,'(F15.3)') ENDIF !## read formation name from grid DO I=1,NLAYR !## write factor related to formation name from grid CALL WGRIDPUTCELLDOUBLE(IDF_GRID1,3,I,IPFAC(I)%FACT,'(F15.3)') ENDDO !## put directory+name of outputfile CALL WDIALOGPUTSTRING(IDF_STRING1,TRIM(OUTPUTFOLDER)) !## put Save option KHV-,KVV,KVA CALL WDIALOGPUTCHECKBOX(IDF_CHECK1,ISAVEK) !## put Save option KDW and VCW CALL WDIALOGPUTCHECKBOX(IDF_CHECK2,ISAVEC) END SUBROUTINE GC_INIT_PREPROCESSING_PUT !###====================================================================== LOGICAL FUNCTION GC_INIT_PREPROCESSING_GET() !###====================================================================== IMPLICIT NONE INTEGER :: I GC_INIT_PREPROCESSING_GET=.FALSE. CALL WDIALOGSELECT(ID_DGEOCONNECT_TAB2) !## get window CALL WDIALOGGETRADIOBUTTON(IDF_RADIO1,IWINDOW) IF(IWINDOW.EQ.1)THEN IDF%NCOL=0; IDF%NROW=0 ELSE CALL WDIALOGGETDOUBLE(IDF_REAL1,IDF%XMIN); CALL WDIALOGGETDOUBLE(IDF_REAL2,IDF%YMIN) CALL WDIALOGGETDOUBLE(IDF_REAL3,IDF%XMAX); CALL WDIALOGGETDOUBLE(IDF_REAL4,IDF%YMAX) CALL WDIALOGGETDOUBLE(IDF_REAL5,IDF%DX); IDF%DY=IDF%DX IF(IDF%DX.LE.0.0D0)THEN CALL WMESSAGEBOX(OKONLY,EXCLAMATIONICON,COMMONOK,'You should specify a CellSize of greater than 0.0D0.','Error') RETURN ENDIF CALL UTL_IDFSNAPTOGRID(IDF%XMIN,IDF%XMAX,IDF%YMIN,IDF%YMAX,IDF%DX,IDF%NCOL,IDF%NROW) ENDIF !## get directory+name of outputfile CALL WDIALOGGETSTRING(IDF_STRING1,OUTPUTFOLDER) IF(TRIM(OUTPUTFOLDER).EQ.'')THEN CALL WMESSAGEBOX(OKONLY,EXCLAMATIONICON,COMMONOK,'You should specify an output folder.','Error') RETURN ENDIF !## get save option KHV-,KVV,KVA CALL WDIALOGGETCHECKBOX(IDF_CHECK1,ISAVEK) !## get save option KDW and VCW CALL WDIALOGGETCHECKBOX(IDF_CHECK2,ISAVEC) !## read formation name from grid DO I=1,NLAYR ! CALL WGRIDGETCELLSTRING(IDF_GRID1,1,I,IPFAC(I)%FORM) !## read factor related to formation name from grid CALL WGRIDGETCELLDOUBLE(IDF_GRID1,3,I,IPFAC(I)%FACT) ENDDO !## set flag GC_IFLAG=2 GC_INIT_PREPROCESSING_GET=.TRUE. END FUNCTION GC_INIT_PREPROCESSING_GET !###====================================================================== SUBROUTINE GC_INIT_POSTPROCESSING_WRITE(FNAME) !###====================================================================== IMPLICIT NONE INTEGER :: IU,IOS,I CHARACTER(LEN=256),INTENT(IN) :: FNAME CHARACTER(LEN=256) :: LINE IU=UTL_GETUNIT() CALL OSD_OPEN(IU,FILE=FNAME,STATUS='UNKNOWN',FORM='FORMATTED',ACTION='WRITE,DENYREAD',IOSTAT=IOS) IF(IOS.NE.0)RETURN WRITE(IU,'(A)') 'FUNCTION=GEOCONNECT' !## write common settings CALL GC_INIT_WRITE(IU,'') WRITE(IU,'(A)') 'DBASEFOLDER='//TRIM(DBASEFOLDER) WRITE(IU,'(A6,I1)') 'IFLAG=',GC_IFLAG IF(IWINDOW.EQ.2)THEN WRITE(IU,'(A,4(F10.2,1X))') 'WINDOW=',IDF%XMIN,IDF%XMAX,IDF%YMIN,IDF%YMAX WRITE(IU,'(A,F10.2)') 'CELLSIZE=',IDF%DX ENDIF WRITE(IU,'(A,I10)') 'NFORM=',SIZE(IPFAC%FORM) DO I=1,SIZE(IPFAC%FORM) LINE='FORM'//TRIM(ITOS(I))//'='//TRIM(IPFAC(I)%FORM)//','//TRIM(ITOS(IPFAC(I)%IGRP)) WRITE(IU,'(A)') TRIM(LINE) ENDDO WRITE(IU,'(A,I10)') 'IAGGR=',IAGGR SELECT CASE (IAGGR) !## model results CASE (1) WRITE(IU,'(A)') 'MODELFOLDER='//TRIM(MODELFOLDER) WRITE(IU,'(A,I10)') 'MODELTYPE=',MODELTYPE !## model input CASE (2) WRITE(IU,'(A,I10)') 'INPUTTYPE=',INPUTTYPE !## ipf-file CASE (3) WRITE(IU,'(A)') 'IPFFILE='//TRIM(IPFFILE) END SELECT WRITE(IU,'(A,I10)') 'IDUPLICATES=',IAGGR_TYPE WRITE(IU,'(A,I10)') 'ISAVETB=',ISAVETB WRITE(IU,'(A)') 'OUTPUTFOLDER='//TRIM(OUTPUTFOLDER) CLOSE(IU) END SUBROUTINE GC_INIT_POSTPROCESSING_WRITE !###====================================================================== LOGICAL FUNCTION GC_INIT_POSTPROCESSING_READ(IU,IMODBATCH) !###====================================================================== IMPLICIT NONE INTEGER,INTENT(IN) :: IU,IMODBATCH INTEGER :: I,J,N,IGRP CHARACTER(LEN=256) :: LINE CHARACTER(LEN=52) :: FORM GC_INIT_POSTPROCESSING_READ=.FALSE. IF(.NOT.UTL_READINITFILE('IFLAG',LINE,IU,0))RETURN READ(LINE,*) GC_IFLAG; WRITE(*,'(A,I2)') 'IFLAG=',GC_IFLAG IF(GC_IFLAG.NE.3)THEN CALL WMESSAGEBOX(OKONLY,EXCLAMATIONICON,COMMONOK,'The choosen INI file is not meant to be read in for the POST-processing tab.','Error') ENDIF OUTPUTFOLDER='' IWINDOW=1 !## read common settings IF(.NOT.GC_INIT_READ(IU,'',IMODBATCH))RETURN !## put settings on tab4 CALL GC_INIT_PUT() IF(UTL_READINITFILE('WINDOW',LINE,IU,1))THEN IWINDOW=2; READ(LINE,*) IDF%XMIN,IDF%YMIN,IDF%XMAX,IDF%YMAX IF(IMODBATCH.EQ.1)WRITE(*,'(A,4(F10.3,1X))') 'WINDOW=',IDF%XMIN,IDF%YMIN,IDF%XMAX,IDF%YMAX IF(.NOT.UTL_READINITFILE('CELLSIZE',LINE,IU,0))RETURN READ(LINE,*) IDF%DX; IDF%DY=IDF%DX IF(IMODBATCH.EQ.1)WRITE(*,'(A,F10.3)') 'CELLSIZE=',IDF%DX IF(IDF%DX.LE.0.0D0)THEN CALL WMESSAGEBOX(OKONLY,EXCLAMATIONICON,COMMONOK,'You should specify a CellSize of greater than 0.0D0.','Error') RETURN ENDIF ENDIF IF(IWINDOW.EQ.1)THEN IDF%NCOL=0; IDF%NROW=0 ELSE CALL UTL_IDFSNAPTOGRID(IDF%XMIN,IDF%XMAX,IDF%YMIN,IDF%YMAX,IDF%DX,IDF%NCOL,IDF%NROW) ENDIF IF(.NOT.UTL_READINITFILE('DBASEFOLDER',LINE,IU,0))RETURN READ(LINE,*) DBASEFOLDER; IF(IMODBATCH.EQ.1)WRITE(*,'(A)') 'DBASEFOLDER='//TRIM(DBASEFOLDER) IF(.NOT.UTL_READINITFILE('NFORM',LINE,IU,0))RETURN READ(LINE,*) N; IF(IMODBATCH.EQ.1)WRITE(*,'(A,I10)') 'NFORM=',N !## check consistency with current geoconnect settings IF(IMODBATCH.EQ.0)THEN ! IF(N.NE.NLAYR)THEN ! CALL WMESSAGEBOX(OKONLY,EXCLAMATIONICON,COMMONOK,'The current ini file does not match with your current GeoConnect settings'//CHAR(13)// & ! 'iMOD found too many geological formation compared to the current ones loading in the GeoConnect Tool','Error') ! RETURN ! ENDIF ELSE NLAYR=N !## started from imodbatch - allocate memory ALLOCATE(IPFAC(NLAYR)) ENDIF !## initialise values IPFAC%IGRP=0 DO I=1,N !LAYR IF(.NOT.UTL_READINITFILE('FORM'//TRIM(ITOS(I)),LINE,IU,0))RETURN READ(LINE,*) FORM,IGRP IF(IMODBATCH.EQ.0)THEN !## make sure to connect with correct formation FORM=UTL_CAP(FORM,'U') DO J=1,NLAYR IF(TRIM(FORM).EQ.TRIM(UTL_CAP(IPFAC(J)%FORM,'U')))THEN; IPFAC(J)%IGRP=IGRP; EXIT; ENDIF ENDDO IF(J.GT.NLAYR)THEN CALL WMESSAGEBOX(OKONLY,EXCLAMATIONICON,COMMONOK,'iMOD cannot find '//TRIM(FORM),'Error') RETURN ENDIF ELSE IPFAC(I)%FORM=FORM; IPFAC(I)%IGRP=IGRP ENDIF LINE='FORM'//TRIM(ITOS(I))//'='//TRIM(IPFAC(I)%FORM)//','//TRIM(ITOS(IPFAC(I)%IGRP)) IF(IMODBATCH.EQ.1)WRITE(*,'(A)') TRIM(LINE) ENDDO IF(.NOT.UTL_READINITFILE('IAGGR',LINE,IU,0))RETURN READ(LINE,*) IAGGR; IF(IMODBATCH.EQ.1)WRITE(*,'(A,I10)') 'IAGGR=',IAGGR SELECT CASE (IAGGR) !## model results CASE (1) IF(.NOT.UTL_READINITFILE('MODELFOLDER',LINE,IU,0))RETURN READ(LINE,*) MODELFOLDER; IF(IMODBATCH.EQ.1)WRITE(*,'(A)') 'MODELFOLDER='//TRIM(MODELFOLDER) IF(.NOT.UTL_READINITFILE('MODELTYPE',LINE,IU,0))RETURN READ(LINE,*) MODELTYPE; IF(IMODBATCH.EQ.1)WRITE(*,'(A,I10)') 'MODELTYPE=',MODELTYPE !## model input CASE (2) IF(.NOT.UTL_READINITFILE('INPUTTYPE',LINE,IU,0))RETURN READ(LINE,*) INPUTTYPE; IF(IMODBATCH.EQ.1)WRITE(*,'(A,I10)') 'INPUTTYPE=',INPUTTYPE !## ipf-file CASE (3) IF(.NOT.UTL_READINITFILE('IPFFILE',LINE,IU,0))RETURN READ(LINE,*) IPFFILE; IF(IMODBATCH.EQ.1)WRITE(*,'(A)') 'IPFFILE='//TRIM(IPFFILE) END SELECT IF(.NOT.UTL_READINITFILE('IDUPLICATES',LINE,IU,0))RETURN READ(LINE,*) IAGGR_TYPE; IF(IMODBATCH.EQ.1)WRITE(*,'(A,I10)') 'IDUPLICATES=',IAGGR_TYPE IF(.NOT.UTL_READINITFILE('ISAVETB',LINE,IU,0))RETURN READ(LINE,*) ISAVETB; IF(IMODBATCH.EQ.1)WRITE(*,'(A,I10)') 'ISAVETB=',ISAVETB IF(.NOT.UTL_READINITFILE('OUTPUTFOLDER',LINE,IU,0))RETURN READ(LINE,*) OUTPUTFOLDER; IF(IMODBATCH.EQ.1)WRITE(*,'(A)') 'OUTPUTFOLDER='//TRIM(OUTPUTFOLDER) GC_INIT_POSTPROCESSING_READ=.TRUE. END FUNCTION GC_INIT_POSTPROCESSING_READ !###====================================================================== SUBROUTINE GC_INIT_POSTPROCESSING_PUT() !###====================================================================== IMPLICIT NONE INTEGER :: I CALL WDIALOGSELECT(ID_DGEOCONNECT_TAB3) !## get window IF(IWINDOW.EQ.1)THEN CALL WDIALOGPUTRADIOBUTTON(IDF_RADIO1) CALL WDIALOGPUTDOUBLE(IDF_REAL1,MPW%XMIN,'(F15.3)'); CALL WDIALOGPUTDOUBLE(IDF_REAL2,MPW%YMIN,'(F15.3)') CALL WDIALOGPUTDOUBLE(IDF_REAL3,MPW%XMAX,'(F15.3)'); CALL WDIALOGPUTDOUBLE(IDF_REAL4,MPW%YMAX,'(F15.3)') CALL WDIALOGPUTDOUBLE(IDF_REAL5,100.0D0,'(F15.3)') ELSEIF(IWINDOW.EQ.2)THEN CALL WDIALOGPUTRADIOBUTTON(IDF_RADIO2) CALL WDIALOGPUTDOUBLE(IDF_REAL1,IDF%XMIN,'(F15.3)'); CALL WDIALOGPUTDOUBLE(IDF_REAL2,IDF%YMIN,'(F15.3)') CALL WDIALOGPUTDOUBLE(IDF_REAL3,IDF%XMAX,'(F15.3)'); CALL WDIALOGPUTDOUBLE(IDF_REAL4,IDF%YMAX,'(F15.3)') CALL WDIALOGPUTDOUBLE(IDF_REAL5,IDF%DX,'(F15.3)') ENDIF !## get dbase-directory+name of outputfile CALL WDIALOGPUTSTRING(IDF_STRING1,DBASEFOLDER) !## write formation name from grid DO I=1,NLAYR !## read factor related to formation name from grid CALL WGRIDPUTCELLINTEGER(IDF_GRID1,3,I,IPFAC(I)%IGRP) ENDDO !## get aggregate option (1=model; 2=input; 3=ipf) SELECT CASE (IAGGR) !## model results CASE (1) CALL WDIALOGPUTRADIOBUTTON(IDF_RADIO3) CALL WDIALOGPUTSTRING(IDF_STRING2,MODELFOLDER) CALL WDIALOGPUTOPTION(IDF_MENU1,MODELTYPE) !## model input CASE (2) CALL WDIALOGPUTRADIOBUTTON(IDF_RADIO4) CALL WDIALOGPUTOPTION(IDF_MENU2,INPUTTYPE) !## ipf-file CASE (3) CALL WDIALOGPUTRADIOBUTTON(IDF_RADIO5) CALL WDIALOGPUTSTRING(IDF_STRING3,IPFFILE) END SELECT !## get aggregate option IF(IAGGR_TYPE.EQ.1)CALL WDIALOGPUTRADIOBUTTON(IDF_RADIO6) IF(IAGGR_TYPE.EQ.2)CALL WDIALOGPUTRADIOBUTTON(IDF_RADIO7) IF(IAGGR_TYPE.EQ.3)CALL WDIALOGPUTRADIOBUTTON(IDF_RADIO8) IF(IAGGR_TYPE.EQ.4)CALL WDIALOGPUTRADIOBUTTON(IDF_RADIO9) !## get dbase-directory+name of outputfile CALL WDIALOGPUTSTRING(IDF_STRING4,TRIM(OUTPUTFOLDER)) !## save top/bottom idf files CALL WDIALOGPUTCHECKBOX(IDF_CHECK1,ISAVETB) END SUBROUTINE GC_INIT_POSTPROCESSING_PUT !###====================================================================== LOGICAL FUNCTION GC_INIT_POSTPROCESSING_GET() !###====================================================================== IMPLICIT NONE INTEGER :: I GC_INIT_POSTPROCESSING_GET=.FALSE. CALL IDFNULLIFY(IDF) CALL WDIALOGSELECT(ID_DGEOCONNECT_TAB3) !## get window CALL WDIALOGGETRADIOBUTTON(IDF_RADIO1,IWINDOW) IF(IWINDOW.EQ.1)THEN IDF%NCOL=0; IDF%NROW=0 ELSE CALL WDIALOGGETDOUBLE(IDF_REAL1,IDF%XMIN); CALL WDIALOGGETDOUBLE(IDF_REAL2,IDF%YMIN) CALL WDIALOGGETDOUBLE(IDF_REAL3,IDF%XMAX); CALL WDIALOGGETDOUBLE(IDF_REAL4,IDF%YMAX) CALL WDIALOGGETDOUBLE(IDF_REAL5,IDF%DX); IDF%DY=IDF%DX IF(IDF%DX.LE.0.0D0)THEN CALL WMESSAGEBOX(OKONLY,EXCLAMATIONICON,COMMONOK,'You should specify a CellSize of greater than 0.0D0.','Error') RETURN ENDIF CALL UTL_IDFSNAPTOGRID(IDF%XMIN,IDF%XMAX,IDF%YMIN,IDF%YMAX,IDF%DX,IDF%NCOL,IDF%NROW) ENDIF !## get dbase-directory+name of outputfile CALL WDIALOGGETSTRING(IDF_STRING1,DBASEFOLDER) IF(TRIM(DBASEFOLDER).EQ.'')THEN CALL WMESSAGEBOX(OKONLY,EXCLAMATIONICON,COMMONOK,'You should specify a DBASE folder.','Error') RETURN ENDIF !## read formation name from grid DO I=1,NLAYR !## read factor related to formation name from grid CALL WGRIDGETCELLINTEGER(IDF_GRID1,3,I,IPFAC(I)%IGRP) ENDDO !## get aggregate option (1=model; 2=input; 3=ipf) CALL WDIALOGGETRADIOBUTTON(IDF_RADIO3,IAGGR) SELECT CASE (IAGGR) !## model results CASE (1) !## get dbase-directory+name of outputfile CALL WDIALOGGETSTRING(IDF_STRING2,MODELFOLDER) IF(TRIM(MODELFOLDER).EQ.'')THEN CALL WMESSAGEBOX(OKONLY,EXCLAMATIONICON,COMMONOK,'You should specify a model results folder.','Error') RETURN ENDIF CALL WDIALOGGETMENU(IDF_MENU1,MODELTYPE) !## model input CASE (2) CALL WDIALOGGETMENU(IDF_MENU2,INPUTTYPE) !## ipf-file CASE (3) !## get ipffile CALL WDIALOGGETSTRING(IDF_STRING3,IPFFILE) IF(TRIM(IPFFILE).EQ.'')THEN CALL WMESSAGEBOX(OKONLY,EXCLAMATIONICON,COMMONOK,'You should specify an ipf-file.','Error') RETURN ENDIF END SELECT !## get aggregate option (1=model; 2=input; 3=ipf) CALL WDIALOGGETRADIOBUTTON(IDF_RADIO6,IAGGR_TYPE) !## get dbase-directory+name of outputfile CALL WDIALOGGETSTRING(IDF_STRING4,OUTPUTFOLDER) IF(TRIM(OUTPUTFOLDER).EQ.'')THEN CALL WMESSAGEBOX(OKONLY,EXCLAMATIONICON,COMMONOK,'You should specify an output folder.','Error') RETURN ENDIF CALL WDIALOGGETCHECKBOX(IDF_CHECK1,ISAVETB) !## set flag GC_IFLAG=3 GC_INIT_POSTPROCESSING_GET=.TRUE. END FUNCTION GC_INIT_POSTPROCESSING_GET !###====================================================================== LOGICAL FUNCTION GC_REGISFILES_GETLIST() !###====================================================================== IMPLICIT NONE INTEGER :: I,II,III,J,K,IU,N,IOS CHARACTER(LEN=256),DIMENSION(:),POINTER :: RFILES CHARACTER(LEN=52),DIMENSION(:),ALLOCATABLE :: RFORM INTEGER,DIMENSION(:),ALLOCATABLE :: IFORM CHARACTER(LEN=52) :: CFORM GC_REGISFILES_GETLIST=.FALSE. IF(ASSOCIATED(RFILES))DEALLOCATE(RFILES); IF(ASSOCIATED(REGISFILES))DEALLOCATE(REGISFILES) !## define subdirections for needed REGIS-files IF(.NOT.UTL_DIRINFO_POINTER(REGISFOLDER,'*-T-C.IDF',RFILES,'F'))RETURN IF(.NOT.ASSOCIATED(RFILES))RETURN !## read stratigraphical order IU=UTL_GETUNIT() CALL OSD_OPEN(IU,FILE=TRIM(REGISFOLDER)//'\GEOSTRATIGRAPHY.TXT',STATUS='OLD',FORM='FORMATTED',ACTION='READ,DENYWRITE',IOSTAT=IOS) IF(IOS.NE.0)RETURN N=0; DO; READ(IU,*,IOSTAT=IOS); IF(IOS.NE.0)EXIT; N=N+1; ENDDO; REWIND(IU) ALLOCATE(RFORM(N),IFORM(N)); IFORM=0 DO I=1,N; READ(IU,*,IOSTAT=IOS)RFORM(I); RFORM(I)=UTL_CAP(RFORM(I),'U'); ENDDO; CLOSE(IU) !## get them in the right order - skip those not mentioned in the geographical order N=0 DO II=1,SIZE(RFILES) J=INDEX(RFILES(II),'\',.TRUE.)+1; K=INDEX(RFILES(II)(J:),'-') !## formation name CFORM=TRIM(RFILES(II)(J:K-1)); CFORM=UTL_CAP(CFORM,'U') !## find location in stratigraphical table DO III=1,SIZE(RFORM) !## find correct formation in order IF(TRIM(CFORM).EQ.TRIM(RFORM(III)))THEN N=N+1; IFORM(III)=1 ENDIF ENDDO ENDDO ALLOCATE(REGISFILES(N)) N=0; DO I=1,SIZE(IFORM) IF(IFORM(I).EQ.1)THEN; N=N+1; REGISFILES(N)=RFORM(I)//'-T-C.IDF'; ENDIF ENDDO IF(ALLOCATED(RFORM))DEALLOCATE(RFORM) IF(ALLOCATED(IFORM))DEALLOCATE(IFORM) !## number of regis files - based upon the top-files NLAYR=SIZE(REGISFILES) IF(ALLOCATED(IPFAC))DEALLOCATE(IPFAC); ALLOCATE(IPFAC(NLAYR)) DO I=1,NLAYR NULLIFY(IPFAC(I)%FVAL); ALLOCATE(IPFAC(I)%FVAL(NLAYM)) IPFAC(I)%FVAL=0.0D0; IPFAC(I)%FACT=1.0D0; IPFAC(I)%IGRP=I J=INDEX(REGISFILES(I),'\',.TRUE.)+1; K=INDEX(REGISFILES(I)(J:),'-') IPFAC(I)%FORM=TRIM(REGISFILES(I)(J:K-1)) IPFAC(I)%FACT=1.0D0 !## get lithology DO J=LEN_TRIM(IPFAC(I)%FORM),1,-1 READ(IPFAC(I)%FORM(J:J),'(I1)',IOSTAT=IOS) II !## read in correct lithology IF(IOS.NE.0)EXIT ENDDO READ(IPFAC(I)%FORM(J:J),'(A1)',IOSTAT=IOS) IPFAC(I)%LITHO IPFAC(I)%LITHO=UTL_CAP(IPFAC(I)%LITHO,'U') SELECT CASE (IPFAC(I)%LITHO) CASE ('Z') !## sand (yellow) IPFAC(I)%LITHOCLR=WRGB(255,255,128) CASE ('K') !## clay (green) IPFAC(I)%LITHOCLR=WRGB(128,128,64) CASE ('V') !## peat (pink) IPFAC(I)%LITHOCLR=WRGB(255,0,255) CASE ('C') !## complex (grey) IPFAC(I)%LITHOCLR=WRGB(200,200,200) CASE ('Q') !## limestone (orange) IPFAC(I)%LITHOCLR=WRGB(255,128,64) CASE ('B') !## browncoal (cyan) IPFAC(I)%LITHOCLR=WRGB(128,255,255) CASE DEFAULT IPFAC(I)%LITHOCLR=WRGB(250,250,250) END SELECT ENDDO GC_REGISFILES_GETLIST=.TRUE. END FUNCTION GC_REGISFILES_GETLIST !###====================================================================== LOGICAL FUNCTION GC_REGISFILES_PUT(DID) !###====================================================================== IMPLICIT NONE INTEGER,INTENT(IN) :: DID INTEGER :: I GC_REGISFILES_PUT=.FALSE. IF(.NOT.ASSOCIATED(REGISFILES))RETURN CALL WDIALOGSELECT(DID) CALL WGRIDROWS(IDF_GRID1,NLAYR) DO I=1,NLAYR CALL WGRIDLABELROW(IDF_GRID1,I,TRIM(ITOS(I))) CALL WGRIDPUTCELLSTRING(IDF_GRID1,1,I,TRIM(IPFAC(I)%LITHO)) CALL WGRIDCOLOURCELL(IDF_GRID1,1,I,-1,IPFAC(I)%LITHOCLR) CALL WGRIDPUTCELLSTRING(IDF_GRID1,2,I,TRIM(IPFAC(I)%FORM)) CALL WGRIDSTATECELL (IDF_GRID1,2,I,2) IF(DID.EQ.ID_DGEOCONNECT_TAB2)THEN CALL WGRIDPUTCELLDOUBLE (IDF_GRID1,3,I,IPFAC(I)%FACT,'(F15.3)') ELSEIF(DID.EQ.ID_DGEOCONNECT_TAB3)THEN CALL WGRIDPUTCELLINTEGER(IDF_GRID1,3,I,IPFAC(I)%IGRP) ENDIF ENDDO GC_REGISFILES_PUT=.TRUE. END FUNCTION GC_REGISFILES_PUT !###====================================================================== LOGICAL FUNCTION GC_REGISFILES_GET() !###====================================================================== IMPLICIT NONE INTEGER :: I GC_REGISFILES_GET=.FALSE. CALL WDIALOGSELECT(ID_DGEOCONNECT_TAB2) DO I=1,NLAYR ! CALL WGRIDGETCELLSTRING(IDF_GRID1,1,I,TRIM(IPFAC(I)%FORM)) ! IF(.NOT.ASSOCIATED(REGISFILES))RETURN CALL WGRIDGETCELLDOUBLE(IDF_GRID1,3,I,IPFAC(I)%FACT) ENDDO GC_REGISFILES_GET=.TRUE. END FUNCTION GC_REGISFILES_GET END MODULE MOD_GEOCONNECT_PAR