!! Copyright (C) Stichting Deltares, 2005-2022. !! !! 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_CREATEIZONE USE MOD_IDF, ONLY : IDFREAD,IDFWRITE,IDFNULLIFY,IDFOBJ,IDFDEALLOCATE,IDFCOPY USE MOD_UTL, ONLY : ITOS,UTL_GETUNIT,UTL_CREATEDIR USE IMODVAR, ONLY : DP_KIND,SP_KIND USE MOD_QKSORT, ONLY : QKSORT_INT CONTAINS !###====================================================================== SUBROUTINE CREATEIZONE_MAIN(FIDF,PFOLDER,OFOLDER,TPARAMETER,NLAY,MINF,IZONEOFFSET,IGROUPOFFSET) !###====================================================================== IMPLICIT NONE CHARACTER(LEN=*),INTENT(IN) :: PFOLDER,OFOLDER,TPARAMETER INTEGER,INTENT(IN) :: NLAY,IZONEOFFSET,IGROUPOFFSET REAL(KIND=DP_KIND),INTENT(IN) :: MINF CHARACTER(LEN=*),INTENT(IN),DIMENSION(:) :: FIDF TYPE(IDFOBJ),ALLOCATABLE,DIMENSION(:) :: IDF CHARACTER(LEN=256) :: LINE INTEGER :: I,J,JZ,NZ,TZ,IROW,ICOL,IG,IU,JU REAL(KIND=DP_KIND) :: F CALL UTL_CREATEDIR(OFOLDER) IU=UTL_GETUNIT(); OPEN(IU,FILE=TRIM(OFOLDER)//'\PARAM.TXT',STATUS='UNKNOWN',ACTION='WRITE') JU=UTL_GETUNIT(); OPEN(JU,FILE=TRIM(OFOLDER)//'\ZONES.TXT',STATUS='UNKNOWN',ACTION='WRITE') ALLOCATE(IDF(NLAY)); DO I=1,SIZE(IDF); CALL IDFNULLIFY(IDF(I)); ENDDO IG=IGROUPOFFSET; NZ=IZONEOFFSET DO J=1,SIZE(FIDF) IG=IG+1 TZ=0 DO I=1,NLAY CALL IDFDEALLOCATE(IDF,SIZE(IDF)) IDF(I)%FNAME=TRIM(PFOLDER)//'\FRACTIONS_L'//TRIM(ITOS(I))//'\'//FIDF(J) IF(IDFREAD(IDF(I),IDF(I)%FNAME,1,IQ=1))THEN JZ=0 DO IROW=1,IDF(I)%NROW; DO ICOL=1,IDF(I)%NCOL !## take fraction only F=MOD(IDF(I)%X(ICOL,IROW),1.0D0) IF(F.GE.MINF)THEN JZ=JZ+1 IF(F.GT.0.99)THEN IDF(I)%X(ICOL,IROW)=REAL(NZ+1) ELSE IDF(I)%X(ICOL,IROW)=REAL(NZ+1)+IDF(I)%X(ICOL,IROW) ENDIF ELSEIF(IDF(I)%X(ICOL,IROW).EQ.1.0D0)THEN JZ=JZ+1; IDF(I)%X(ICOL,IROW)=REAL(NZ+1) ELSE IDF(I)%X(ICOL,IROW)=0.0D0 ENDIF ENDDO; ENDDO TZ=TZ+JZ IF(JZ.GT.0)THEN NZ=NZ+1 IDF(I)%FNAME=TRIM(OFOLDER)//'\FRACTIONS_L'//TRIM(ITOS(I))//'\'//TRIM(FIDF(J)) IF(.NOT.IDFWRITE(IDF(I),IDF(I)%FNAME,1))RETURN WRITE(LINE,'(I3,A4,2(I3,A1),5(F5.2,A1),I3)') 1,','//TRIM(TPARAMETER)//',',I,',',NZ,',',1.0D0,',',1.1,',',0.1,',',10.0D0,',',10.0D0,',',IG WRITE(IU,'(A)') TRIM(LINE) WRITE(JU,'(A)') TRIM(IDF(I)%FNAME) ENDIF ENDIF ENDDO IF(TZ.LE.0)IG=IG-1 ENDDO END SUBROUTINE CREATEIZONE_MAIN !###====================================================================== SUBROUTINE CREATEIZONE_LITHOS(FIDF,OFOLDER,TPARAMETER,NLAY,IZONEOFFSET,IGROUPOFFSET) !###====================================================================== IMPLICIT NONE CHARACTER(LEN=*),INTENT(IN) :: OFOLDER,TPARAMETER INTEGER,INTENT(IN) :: NLAY,IZONEOFFSET,IGROUPOFFSET CHARACTER(LEN=*),INTENT(IN),DIMENSION(:) :: FIDF TYPE(IDFOBJ),ALLOCATABLE,DIMENSION(:) :: LIDF,ZIDF INTEGER :: ILAY,IROW,ICOL,I,J,K,NULIST,IU,IZ,IG INTEGER,DIMENSION(:),ALLOCATABLE :: ULIST,PLIST INTEGER,DIMENSION(:,:),ALLOCATABLE :: NUZON CHARACTER(LEN=15),DIMENSION(:),ALLOCATABLE :: CULIST ALLOCATE(LIDF(NLAY)); DO ILAY=1,NLAY; CALL IDFNULLIFY(LIDF(ILAY)); IF(.NOT.IDFREAD(LIDF(ILAY),FIDF(ILAY),1))STOP; ENDDO ALLOCATE(ZIDF(NLAY)); DO ILAY=1,NLAY; CALL IDFNULLIFY(ZIDF(ILAY)); CALL IDFCOPY(LIDF(ILAY),ZIDF(ILAY)); ENDDO !## read lithos and determine unique if not specified I=MAXVAL(LIDF%NCOL)*MAXVAL(LIDF%NROW); ALLOCATE(ULIST(I)); ULIST=0; NULIST=0 DO ILAY=1,NLAY; DO IROW=1,LIDF(ILAY)%NROW; DO ICOL=1,LIDF(ILAY)%NCOL IF(LIDF(ILAY)%X(ICOL,IROW).NE.LIDF(ILAY)%NODATA)THEN I=INT(LIDF(ILAY)%X(ICOL,IROW)) LIDF(ILAY)%X(ICOL,IROW)=REAL(I,8) DO J=1,NULIST; IF(I.EQ.ULIST(J))EXIT; ENDDO IF(J.GT.NULIST)THEN; NULIST=NULIST+1; ULIST(NULIST)=I; ENDIF ENDIF ENDDO; ENDDO; ENDDO !## sort ulist CALL QKSORT_INT(NULIST,ULIST) !## make a pivottable ALLOCATE(PLIST(MAXVAL(ULIST))); PLIST=0 DO J=1,NULIST PLIST(ULIST(J))=J ENDDO !## echo found unique-values ALLOCATE(CULIST(NULIST),NUZON(NULIST,NLAY)); CULIST=''; NUZON=0 DO ILAY=1,NLAY DO IROW=1,LIDF(ILAY)%NROW; DO ICOL=1,LIDF(ILAY)%NCOL IF(LIDF(ILAY)%X(ICOL,IROW).NE.LIDF(ILAY)%NODATA)THEN I=INT(LIDF(ILAY)%X(ICOL,IROW)) IZ=PLIST(I) ! DO J=1,NULIST; IF(I.EQ.ULIST(J))EXIT; ENDDO !## get new zone number ! IZ=J; NUZON(IZ,ILAY)=NUZON(IZ,ILAY)+1 !IZ ENDIF ENDDO; ENDDO ENDDO WRITE(*,'(/5(A15,1X))') 'LAYER','ZONENUMBER','LITHOCODE','GROUPNUMBER','ACRONYM' IZ=IZONEOFFSET DO ILAY=1,NLAY IG=IGROUPOFFSET DO I=1,NULIST IG=IG+1 IZ=IZ+1 IF(NUZON(I,ILAY).GT.0)THEN CULIST(I)=TRIM(TPARAMETER)//'_LITHO'//TRIM(ITOS(ULIST(I))) WRITE(*,'(4(I15,1X),A15)') ILAY,IZ,ULIST(I),IG,TRIM(CULIST(I)) ENDIF ENDDO ENDDO CALL UTL_CREATEDIR(OFOLDER) IU=UTL_GETUNIT(); OPEN(IU,FILE=TRIM(OFOLDER)//'\IPEST.PRJ',STATUS='UNKNOWN',ACTION='WRITE') I=0; DO ILAY=1,NLAY DO IZ=1,NULIST IF(NUZON(IZ,ILAY).GT.0)I=I+1 ENDDO ENDDO WRITE(IU,'(A)') TRIM(ITOS(I))//',(PST) PARAMETER ESTIMATION [-],1' WRITE(IU,'(A)') '[<0=interpolation or >0]' WRITE(IU,'(A)') ',,,,,,' WRITE(IU,'(A)') ',0.0,0.1,0,0,1.0,0.0,3,,0.0,2' DO ILAY=1,NLAY IG=IGROUPOFFSET IZ=IZONEOFFSET DO I=1,NULIST IG=IG+1 IZ=IZ+1 IF(NUZON(I,ILAY).GT.0)THEN WRITE(IU,'(A)') ' 1,'//TRIM(TPARAMETER)//','//TRIM(ITOS(ILAY))//','// & TRIM(ITOS(IZ+(ILAY-1)*NULIST))//',1.0,1.1,0.1,10.0,10.0,'//TRIM(ITOS(IG))//',1,'//TRIM(CULIST(I)) !## fill in idf with zone number DO IROW=1,LIDF(ILAY)%NROW; DO ICOL=1,LIDF(ILAY)%NCOL if(icol.eq.552.and.irow.eq.207.and.ilay.eq.27)then write(*,*) endif IF(LIDF(ILAY)%X(ICOL,IROW).NE.LIDF(ILAY)%NODATA)THEN K=INT(LIDF(ILAY)%X(ICOL,IROW)) J=PLIST(K) IF(J.EQ.IZ)ZIDF(ILAY)%X(ICOL,IROW)=IZ+(ILAY-1)*NULIST ENDIF ENDDO; ENDDO ENDIF ENDDO ENDDO WRITE(IU,'(A)') TRIM(ITOS(NLAY)) DO ILAY=1,NLAY IF(.NOT.IDFWRITE(ZIDF(ILAY),TRIM(OFOLDER)//'\ZONE_L'//TRIM(ITOS(ILAY))//'.IDF',1))STOP WRITE(IU,'(A)') TRIM(OFOLDER)//'\ZONE_L'//TRIM(ITOS(ILAY))//'.IDF' ENDDO CLOSE(IU); DEALLOCATE(CULIST,ULIST,PLIST) CALL IDFDEALLOCATE(ZIDF,SIZE(ZIDF)); CALL IDFDEALLOCATE(LIDF,SIZE(LIDF)) END SUBROUTINE CREATEIZONE_LITHOS END MODULE MOD_CREATEIZONE