c Copyright (C) Stichting Deltares, 2005-2014.
c
c This file is part of iMOD.
c
c This program is free software: you can redistribute it and/or modify
c it under the terms of the GNU General Public License as published by
c the Free Software Foundation, either version 3 of the License, or
c (at your option) any later version.
c
c This program is distributed in the hope that it will be useful,
c but WITHOUT ANY WARRANTY; without even the implied warranty of
c MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
c GNU General Public License for more details.
c
c You should have received a copy of the GNU General Public License
c along with this program. If not, see .
c
c Contact: imod.support@deltares.nl
c Stichting Deltares
c P.O. Box 177
c 2600 MH Delft, The Netherlands.
c
c iMod is partly based on the USGS MODFLOW2005 source code;
c for iMOD the USGS MODFLOW2005 source code has been expanded
c and extensively modified by Stichting Deltares.
c The original USGS MODFLOW2005 source code can be downloaded from the USGS
c website http://www.usgs.gov/. The original MODFLOW2005 code incorporated
c in this file is covered by the USGS Software User Rights Notice;
c you should have received a copy of this notice along with this program.
c If not, see .
c component version of mf2005 main program
C ******************************************************************
C MAIN CODE FOR U.S. GEOLOGICAL SURVEY MODULAR MODEL -- MODFLOW-2005
C ******************************************************************
C
C SPECIFICATIONS:
C ------------------------------------------------------------------
C1------USE package modules.
module m_mf2005_main
USE GLOBAL
USE GWFBASMODULE
USE GWFHUFMODULE, ONLY:IOHUFHDS,IOHUFFLWS
USE GWFEVTMODULE, ONLY:NEVTOP
USE GWFRCHMODULE, ONLY:NRCHOP
USE GWFLAKMODULE, ONLY:NLAKESAR,THETA,STGOLD,STGNEW,VOL
USE GWFUZFMODULE, ONLY: IUZFBND, FINF, VKS
USE PCGMODULE
c USE LMGMODULE
USE SIPMODULE
USE DE4MODULE
USE GMGMODULE
integer, private :: i ! integer i is used in include file openspec.inc
INCLUDE 'openspec.inc'
C
C-------ASSIGN VERSION NUMBER AND DATE
CHARACTER*40 VERSION
CHARACTER*10 MFVNAM
PARAMETER (VERSION='1.8.00 12/18/2009')
PARAMETER (MFVNAM='-2005')
C
CHARACTER*80 HEADNG(2)
CHARACTER*200 FNAME
INTEGER IBDT(8)
integer :: inunit
C
CHARACTER*4 CUNIT(NIUNIT)
DATA CUNIT/'BCF6', 'WEL ', 'DRN ', 'RIV ', 'EVT ', ' ', 'GHB ', ! 7
& 'RCH ', 'SIP ', 'DE4 ', ' ', 'OC ', 'PCG ', 'lmg ', ! 14
& 'gwt ', 'FHB ', 'RES ', 'STR ', 'IBS ', 'CHD ', 'HFB6', ! 21
& 'LAK ', 'LPF ', 'DIS ', ' ', 'PVAL', ' ', 'HOB ', ! 28
& ' ', ' ', 'ZONE', 'MULT', 'DROB', 'RVOB', 'GBOB', ! 35
& 'STOB', 'HUF2', 'CHOB', 'ETS ', 'DRT ', ' ', 'GMG ', ! 42
& 'HYD ', 'SFR ', ' ', 'GAGE', 'LVDA', ' ', 'LMT6', ! 49
& 'MNW2', 'MNWI', 'MNW1', 'KDEP', 'SUB ', 'UZF ', 'gwm ', ! 56
& 'SWT ', 'cfp ', 'PWT ', ' ', ' ', 'SCR ', 'nrs ', ! 63 ! DLT: SUB-Creep (62) added
& 'DXC ', 'ANI ', ' ', ' ', 'MET ',
& 32*' '/ ! 64: Data eXChange
integer, save, pointer :: nsol
integer, save, pointer :: iouts
integer, save, pointer :: kper,kkper,kstp,kkstp,kiter,kkiter
integer, save, pointer :: icnvg
integer, save, pointer :: ilmtfmt,issmt3d,iumt3d
double precision, save, pointer :: timesteptime ! absolute time value of the
! start of the current time step
logical, save, pointer :: initTimeStep ! .true. read timestep data
! .false. donĀ“t read anything
! set in *_prepareTimeStep()
! used in *_initTimeStep()
logical, save, pointer :: timeStepCalculated ! .true. timestep calculated and converged
! .false. calculation of timestep not ready yet
logical, save, pointer :: solverConverged ! .true. last _performIter has converged
type mitype
! multi instance type
! modflow 2005 variables
integer, pointer :: nsol
integer, pointer :: iouts
integer, pointer :: kper,kkper,kstp,kkstp,kiter,kkiter
integer, pointer :: icnvg
integer, pointer :: ilmtfmt,issmt3d,iumt3d
double precision, pointer :: timesteptime
logical, pointer :: initTimeStep
logical, pointer :: timeStepCalculated
logical, pointer :: solverConverged
end type
type(mitype), save :: mi(10)
integer, save :: ninstance=1
! integer, save :: ninstance=0
end module m_mf2005_main
c ******************************************************************************
subroutine mf2005_initComponent(record,retVal)
C ------------------------------------------------------------------
C create instance for mf2005 run, igrid is generated
use m_mf2005_main
use m_mf2005_iu
implicit none
c arguments
character (len=*), intent(in) :: record ! initialisation record
! if empty: the commandline arguments
! will be used instead
integer , intent(out) :: retVal ! return value: 0=OK
c local variables
integer :: maxunit,nc,i
integer :: igrid
logical :: lfname
c init
retVal = 0
C2------WRITE BANNER TO SCREEN AND DEFINE CONSTANTS.
WRITE (*,1) MFVNAM,VERSION
1 FORMAT (/,34X,'MODFLOW',A,/,
&4X,'U.S. GEOLOGICAL SURVEY MODULAR FINITE-DIFFERENCE',
&' GROUND-WATER FLOW MODEL',/,29X,'Version ',A/)
INUNIT = 99
c-------process argument record ! DLT
if (retVal.eq.0) then ! DLT
call mf2005_args(record,lfname,igrid,retVal) ! DLT
endif ! DLT
if (retVal.ne.0) return ! DLT
C
C3------GET THE NAME OF THE NAME FILE
if (lfname) then ! DLT
CALL GETNAMFIL(FNAME)
endif ! DLT
MAXUNIT= INUNIT
C
C4------OPEN NAME FILE.
OPEN (UNIT=INUNIT,FILE=FNAME,STATUS='OLD',ACTION=ACTION(1))
NC=INDEX(FNAME,' ')
WRITE(*,490)' Using NAME file: ',FNAME(1:NC)
490 FORMAT(A,A)
C
C5------Get current date and time, assign to IBDT, and write to screen
CALL DATE_AND_TIME(VALUES=IBDT)
WRITE(*,2) (IBDT(I),I=1,3),(IBDT(I),I=5,7)
2 FORMAT(1X,'Run start date and time (yyyy/mm/dd hh:mm:ss): ',
&I4,'/',I2.2,'/',I2.2,1X,I2,':',I2.2,':',I2.2,/)
C
C6------ALLOCATE AND READ (AR) PROCEDURE
cDLT IGRID=1
NSOL=1
CALL GWF2BAS7AR(INUNIT,CUNIT,VERSION,24,31,32,MAXUNIT,IGRID,12,
1 HEADNG,26,MFVNAM)
IF(IUNIT(IUMNW2).GT.0 .AND. IUNIT(IUMNW1).GT.0) THEN
WRITE(IOUT,'(1X,/,1X,A)')
1 'MNW1 and MNW2 cannot both be active in the same simulation'
CALL USTOP(' ')
END IF
c-------process argument record for setting time ! DLT
call mf2005_args_time(record,igrid) ! DLT
C -----SAVE POINTERS TO DATA AND RETURN.
c CALL SGWF2INS1PSV(IGRID) ! DLT: instances
return
end
c ******************************************************************************
subroutine mf2005_initSimulationWrp0()
! wrapper routine
implicit none
! local variables
integer :: retVal
! functions
double precision :: currentTime
! ------------------------------
call mf2005_getCurrentTime(currentTime,retVal)
call mf2005_initSimulation(currentTime,retVal)
return
end
c =======
subroutine mf2005_initSimulation(currentTime,retVal)
use m_mf2005_main
use m_mf2005_iu
implicit none
c arguments
double precision, intent(in) :: currentTime
integer , intent(out) :: retVal
c local variable
integer :: igrid
double precision, parameter :: dnull=0.d0
c functions
double precision :: cfn_mjd_delta
c init
retVal=0
c program
do igrid=1,ninstance ! DLT: instances
call sgwf2ins1pnt(igrid) DLT: instances
call SGWF2BAS7PNT(IGRID) ! DLT: instances
! check current time value ! DLT: components
if (cfn_mjd_delta(currentTime,timesteptime).ne.dnull) then ! DLT: components
write(*,*) ! DLT: components
1 ' ERROR, current time not equal to Modflow time: ', ! DLT: components
1 currentTime,timesteptime ! DLT: components
retVal=-1 ! DLT: components
return ! DLT: components
endif ! DLT: components
timeStepCalculated = .false. ! DLT: components
IF(IUNIT(IUBCF6).GT.0) CALL GWF2BCF7AR(IUNIT(IUBCF6),IGRID)
IF(IUNIT(IULPF).GT.0) CALL GWF2LPF7AR(IUNIT(IULPF),IGRID)
if(IUNIT(IUPWT).gt.0) call gwf2pwt3ar(IUNIT(IUPWT),IUNIT(IUBCF6),
1 igrid,iout) ! PWT3
if(IUNIT(IUANI).gt.0) call gwf2ani3ar(IUNIT(IUANI), ! ANI
1 IUNIT(IUPWT),igrid) ! ANI
IF(IUNIT(IUHUF2).GT.0) CALL GWF2HUF7AR(IUNIT(IUHUF2),
1 IUNIT(IULVDA),IUNIT(IUKDEP),IGRID)
IF(IUNIT(IUWEL).GT.0) CALL GWF2WEL7AR(IUNIT(IUWEL),IGRID)
IF(IUNIT(IUDRN).GT.0) CALL GWF2DRN7AR(IUNIT(IUDRN),IGRID)
IF(IUNIT(IURIV).GT.0) CALL GWF2RIV7AR(IUNIT(IURIV),IGRID)
IF(IUNIT(IUEVT).GT.0) CALL GWF2EVT7AR(IUNIT(IUEVT),IGRID)
IF(IUNIT(IUGHB).GT.0) CALL GWF2GHB7AR(IUNIT(IUGHB),IGRID)
IF(IUNIT(IURCH).GT.0) CALL GWF2RCH7AR(IUNIT(IURCH),IGRID)
IF(IUNIT(IUFHB).GT.0) CALL GWF2FHB7AR(IUNIT(IUFHB),IGRID)
IF(IUNIT(IURES).GT.0) CALL GWF2RES7AR(IUNIT(IURES),IGRID)
IF(IUNIT(IUSTR).GT.0) CALL GWF2STR7AR(IUNIT(IUSTR),IGRID)
IF(IUNIT(IUIBS).GT.0) CALL GWF2IBS7AR(IUNIT(IUIBS),
1 IUNIT(IUSUB),IGRID)
IF(IUNIT(IUCHD).GT.0) CALL GWF2CHD7AR(IUNIT(IUCHD),IGRID)
IF(IUNIT(IUHFB6).GT.0) CALL GWF2HFB7AR(IUNIT(IUHFB6),IGRID)
IF(IUNIT(IUSFR).GT.0) CALL GWF2SFR7AR(IUNIT(IUSFR),IUNIT(IUBCF6),
1 IUNIT(IULPF), IUNIT(IUHUF2),IUNIT(IUGWT),NSOL,IOUTS,IGRID)
IF(IUNIT(IUUZF).GT.0) CALL GWF2UZF1AR(IUNIT(IUUZF),IUNIT(IUBCF6),
1 IUNIT(IULPF),IUNIT(IUHUF2),IGRID)
IF(IUNIT(IULAK).GT.0 .OR. IUNIT(IUSFR).GT.0) CALL GWF2LAK7AR(
1 IUNIT(IULAK),IUNIT(IUSFR),IUNIT(IUGWT),IUNIT(IUUZF),
1 NSOL,IGRID)
IF(IUNIT(IUGAGE).GT.0) CALL GWF2GAG7AR(IUNIT(IUGAGE),IUNIT(IUSFR),
1 IUNIT(IULAK),IGRID)
IF(IUNIT(IUETS).GT.0) CALL GWF2ETS7AR(IUNIT(IUETS),IGRID)
IF(IUNIT(IUDRT).GT.0) CALL GWF2DRT7AR(IUNIT(IUDRT),IGRID)
IF(IUNIT(IUSUB).GT.0) CALL GWF2SUB7AR(IUNIT(IUSUB),IGRID)
IF(IUNIT(IUSIP).GT.0) CALL SIP7AR(IUNIT(IUSIP),MXITER,IGRID)
IF(IUNIT(IUDE4).GT.0) CALL DE47AR(IUNIT(IUDE4),MXITER,IGRID)
IF(IUNIT(IUPCG).GT.0) CALL PCG7AR(IUNIT(IUPCG),MXITER,IGRID)
c IF(IUNIT(IULMG).GT.0) CALL LMG7AR(IUNIT(IULMG),MXITER,IGRID)
IF(IUNIT(42).GT.0) CALL GMG7AR(IUNIT(42),MXITER,IGRID)
IF(IUNIT(IUMNW2).GT.0) CALL GWF2MNW27AR(IUNIT(IUMNW2),IGRID)
IF(IUNIT(IUMNWI).GT.0) CALL GWF2MNW2I7AR(IUNIT(IUMNWI),
1 IUNIT(IUMNW2),IGRID)
IF(IUNIT(IUMNW1).GT.0) CALL GWF2MNW17AR(IUNIT(IUMNW1),
1 IUNIT(IUSIP),IUNIT(IUDE4),0,IUNIT(IUPCG),
2 0,IUNIT(42),FNAME,IGRID)
IF(IUNIT(IUSWT).GT.0) CALL GWF2SWT7AR(IUNIT(IUSWT),IGRID)
c SUB-Creep
IF(IUNIT(IUSCR).GT.0) THEN
CALL GWF2SCR7AR(IUNIT(IUSCR),IGRID)
!calculate a priori time steps which will be later used by MODFLOW
CALL GWF2SCR1TM(IGRID)
END IF
C SUB-Creep end
IF(IUNIT(IUHYD).GT.0) CALL GWF2HYD7BAS7AR(IUNIT(IUHYD),IGRID)
IF(IUNIT(IUHYD).GT.0 .AND. IUNIT(IUIBS).GT.0)
1 CALL GWF2HYD7IBS7AR(IUNIT(IUHYD),IGRID)
IF(IUNIT(IUHYD).GT.0 .AND. IUNIT(IUSUB).GT.0)
1 CALL GWF2HYD7SUB7AR(IUNIT(IUHYD),IGRID)
IF(IUNIT(IUHYD).GT.0 .AND. IUNIT(IUSTR).GT.0)
1 CALL GWF2HYD7STR7AR(IUNIT(IUHYD),IGRID)
IF(IUNIT(IUHYD).GT.0 .AND. IUNIT(IUSFR).GT.0)
1 CALL GWF2HYD7SFR7AR(IUNIT(IUHYD),IGRID)
IF(IUNIT(IUDXC).GT.0) CALL gwf2dxc1AR(IUNIT(IUDXC),IGRID) ! DLT: Data eXChance package
C
C Observation allocate and read
CALL OBS2BAS7AR(IUNIT(IUHOB),IGRID)
IF(IUNIT(IUDROB).GT.0) CALL OBS2DRN7AR(IUNIT(IUDROB),
1 IUNIT(IUDRN),IGRID)
IF(IUNIT(IURVOB).GT.0) CALL OBS2RIV7AR(IUNIT(IURVOB),
1 IUNIT(IURIV),IGRID)
IF(IUNIT(IUGBOB).GT.0) CALL OBS2GHB7AR(IUNIT(IUGBOB),
1 IUNIT(IUGHB),IGRID)
IF(IUNIT(IUSTOB).GT.0) CALL OBS2STR7AR(IUNIT(IUSTOB),
1 IUNIT(IUSTR),IGRID)
IF(IUNIT(IUCHOB).GT.0) CALL OBS2CHD7AR(IUNIT(IUCHOB),IGRID)
! init timestep
kper=0
enddo ! DLT: instances
C
return
end
c ******************************************************************************
subroutine mf2005_prepareTimestepWrp0(deltats,endOfSimulation)
! wrapper routine
! this routine will always advance one timestep
use m_mf2005_main, only: mi
implicit none
! arguments
integer, intent(inout) :: deltats ! set timstep increment
logical, intent(inout) :: endOfSimulation ! set value to .true. if end of simulation is reached
! otherwise DON'T change this vallue
! local variables
integer :: igrid
integer :: retVal
logical :: stateSave
double precision :: currentTime
! functions
double precision :: sutl_getTimeStepLength
! ------------------------------
! add timesteplength to current time
! use timestep of model(igrid=1)
igrid=1
currentTime=mi(igrid)%timesteptime
currentTime=currentTime+sutl_getTimeStepLength(igrid)
stateSave =.false.
call mf2005_prepareTimestep(currentTime,stateSave,retVal)
! check return value
if (retVal.ne.0) then
endOfSimulation=.true.
else
deltats=min(deltats,1) ! advance maximum 1 timestep forward
endif
return
end
c =======
subroutine mf2005_prepareTimestep(currentTime,saveState,retVal,
$kper2,kstp2)
use m_mf2005_main
implicit none
c arguments
double precision, intent(in) :: currentTime
logical , intent(in) :: saveState
integer , intent(out) :: retVal
integer , intent(out), optional :: kper2, kstp2
c integer, intent(inout) :: deltats ! set timstep increment
c logical, intent(inout) :: endOfSimulation ! set value to .true. if end of simulation is reached
c ! otherwise DON'T change this vallue
c local variable
integer :: igrid
logical :: initstress,inittime
double precision :: dt
c functions
double precision :: cfn_mjd_delta
c ------------------------------------------------------------------------------
! init
retVal=0
do igrid=1,ninstance ! DLT: instances
call sgwf2ins1pnt(igrid) ! DLT: instances
call SGWF2BAS7PNT(IGRID) ! DLT: instances
! find out whether the model has to advance to the next timestep ! DLT: components
dt = cfn_mjd_delta(currentTime,timesteptime) ! DLT: components
! DLT: components
! check restore timestep ! DLT: components
if (dt.lt.0.d0) then ! DLT: components
! restore timestep ! DLT: components
write(*,'(a,f20.5)') ' RESTORE STATE: MF2005 ',currentTime
call mf2005_staterestore(currentTime) ! DLT: components
else if (dt.eq.0.d0 .and. timeStepCalculated) then ! DLT: components
! calculate timestep again, restoreState needed ! DLT: components
write(*,'(a,f20.5)') ' RESTORE STATE: MF2005 ',currentTime
call mf2005_staterestore(currentTime) ! DLT: components
else ! DLT: components
! save timestep (only when no restore has to be done) ! DLT: components
if (saveState) then ! DLT: components
write(*,'(a,f20.5)') ' SAVE STATE: MF2005 ',currentTime
call mf2005_statesave(currentTime) ! DLT: components
endif ! DLT: components
endif ! DLT: components
! DLT: components
initTimeStep=.true. ! DLT: components
! set new time value
timesteptime=currentTime
c get next timestep
if (initTimeStep) then
initstress=.false.
if (kper.eq.0) then
! first timestep
initstress=.true.
inittime =.true.
else
! check end of stress period
if (kstp.ge.nstp(kper)) then
! new stress period needed
if (kper.ge.nper) then
! this was the last stress period
initstress=.false.
inittime =.false.
else
! new stress period, new timestep
initstress=.true.
inittime =.true.
endif
else
! same stress period, new timestep
initstress=.false.
inittime =.true.
endif
endif
c next stress period
if (initstress) then
kper =kper+1
kkper=kper
kstp=0
endif
c next time step
if (inittime) then
c deltats=min(deltats,1) ! advance maximum 1 timestep forward
kstp =kstp+1
kkstp=kstp
endif
c find out or this is end of simulation
if (.not. inittime) then
! endOfSimulation=.true.
initTimeStep=.false.
retVal=-1
endif
c init solve
kiter =0
kkiter=kiter
if (initTimeStep) then
timeStepCalculated = .false.
solverConverged = .false.
endif
endif
enddo ! DLT: instances
C
if (present(kper2)) then
kper2=kper
endif
if (present(kstp2)) then
kstp2 = kstp
endif
return
end
c ******************************************************************************
subroutine mf2005_initTimeStepWrp0(restore)
! wrapper routine
implicit none
c arguments
logical, intent(in) :: restore ! force reading data
! local variables
integer :: retVal
double precision :: currentTime
! ------------------------------
call mf2005_getCurrentTime(currentTime,retVal)
call mf2005_initTimeStep(currentTime,retVal)
return
end
c =======
subroutine mf2005_initTimeStep(currentTime,retVal)
use m_mf2005_main
use m_mf2005_iu
implicit none
c arguments
double precision, intent(in) :: currentTime ! not used at this moment
! Necessary information comes from _prepareTimeStep
! by using variable initTimeStep
integer , intent(out) :: retVal
c local variable
integer :: igrid
logical initstress,inittime
c ------------------------------------------------------------------------------
c init
retVal = 0
do igrid=1,ninstance ! DLT: instances
c call sgwf2ins1pnt(igrid) ! DLT: instances
call SGWF2BAS7PNT(IGRID) ! DLT: instances
KKPER = KPER
kkstp = kstp ! DLT: instances
c check what to read
if (kstp.eq.1) then
initstress=.true. .and. initTimeStep
inittime =.true. .and. initTimeStep
else
initstress=.false. .and. initTimeStep
inittime =.true. .and. initTimeStep
endif
c next stress period
if (initstress) then
C7------SIMULATE EACH STRESS PERIOD.
c DO 100 KPER = 1, NPER
CALL GWF2BAS7ST(KKPER,IGRID)
IF(IUNIT(IUIBS).GT.0) CALL GWF2IBS7ST(KKPER,IGRID)
IF(IUNIT(IUSUB).GT.0) CALL GWF2SUB7ST(KKPER,IGRID)
IF(IUNIT(IUSWT).GT.0) CALL GWF2SWT7ST(KKPER,IGRID)
c SUB-Creep
IF(IUNIT(IUSCR).GT.0) CALL GWF2SCR7ST(KKPER,IGRID)
c SUB-Creep end
C7B-----READ AND PREPARE INFORMATION FOR STRESS PERIOD.
C----------READ USING PACKAGE READ AND PREPARE MODULES.
IF(IUNIT(IUWEL).GT.0) CALL GWF2WEL7RP(IUNIT(IUWEL),IGRID)
IF(IUNIT(IURIV).GT.0) CALL GWF2RIV7RP(IUNIT(IURIV),IGRID)
IF(IUNIT(IUDRN).GT.0) CALL GWF2DRN7RP(IUNIT(IUDRN),IGRID,
1 IUNIT(IURIV))
IF(IUNIT(IUEVT).GT.0) CALL GWF2EVT7RP(IUNIT(IUEVT),IGRID)
IF(IUNIT(IUGHB).GT.0) CALL GWF2GHB7RP(IUNIT(IUGHB),IGRID)
IF(IUNIT(IURCH).GT.0) CALL GWF2RCH7RP(IUNIT(IURCH),IGRID)
IF(IUNIT(IURES).GT.0) CALL GWF2RES7RP(IUNIT(IURES),IGRID)
IF(IUNIT(IUSTR).GT.0) CALL GWF2STR7RP(IUNIT(IUSTR),IGRID)
IF(IUNIT(IUHYD).GT.0 .AND. IUNIT(IUSTR).GT.0)
1 CALL GWF2HYD7STR7RP(IUNIT(IUHYD),KKPER,IGRID)
IF(IUNIT(IUCHD).GT.0) CALL GWF2CHD7RP(IUNIT(IUCHD),IGRID)
IF(IUNIT(IUSFR).GT.0) CALL GWF2SFR7RP(IUNIT(IUSFR),IUNIT(IUGWT),
1 IUNIT(IULAK),KKPER,NSOL,
2 IOUTS,IGRID)
IF(IUNIT(IUHYD).GT.0 .AND. IUNIT(IUSFR).GT.0)
1 CALL GWF2HYD7SFR7RP(IUNIT(IUHYD),KKPER,IGRID)
IF(IUNIT(IUUZF).GT.0) CALL GWF2UZF1RP(IUNIT(IUUZF),KKPER,IGRID)
IF(IUNIT(IULAK).GT.0) CALL GWF2LAK7RP(IUNIT(IULAK),
1 IUNIT(IUBCF6),
1 IUNIT(IUGWT),IUNIT(IULPF),IUNIT(IUHUF2),
1 IUNIT(IUSFR),IUNIT(IUUZF),
2 KKPER,NSOL,IOUTS,IGRID)
IF(IUNIT(IUGAGE).GT.0.AND.KKPER.EQ.1)
1 CALL GWF2GAG7RP(IUNIT(IUGWT),
1 IUNIT(IULAK),IUNIT(IUUZF),NSOL,IGRID)
IF(IUNIT(IUETS).GT.0) CALL GWF2ETS7RP(IUNIT(IUETS),IGRID)
IF(IUNIT(IUDRT).GT.0) CALL GWF2DRT7RP(IUNIT(IUDRT),IGRID)
IF(IUNIT(IUMNW2).GT.0) CALL GWF2MNW27RP(IUNIT(IUMNW2),KKPER,
1 IUNIT(IUSIP),
1 IUNIT(IUDE4),0,IUNIT(IUPCG),0,IUNIT(42),0,
1 IGRID)
IF(IUNIT(IUMNWI).GT.0.AND.KKPER.EQ.1)
1 CALL GWF2MNW2I7RP(IUNIT(IUMNWI),0,IGRID)
IF(IUNIT(IUMNW1).GT.0) CALL GWF2MNW17RP(IUNIT(IUMNW1),
1 IUNIT(IUBCF6),
1 IUNIT(IULPF),IUNIT(IUHUF2),KKPER,IGRID)
IF(IUNIT(IUDXC).GT.0) CALL gwf2dxc1rp(igrid) ! DLT: Data eXChance package
endif ! next stress period
c next time step
if (inittime) then
C
C7C-----SIMULATE EACH TIME STEP.
c DO 90 KSTP = 1, NSTP(KPER)
KKSTP = KSTP
C
C7C1----CALCULATE TIME STEP LENGTH. SET HOLD=HNEW.
CALL GWF2BAS7AD(KKPER,KKSTP,IGRID)
IF(IUNIT(IUCHD).GT.0) CALL GWF2CHD7AD(KKPER,IGRID)
IF(IUNIT(IUBCF6).GT.0) CALL GWF2BCF7AD(KKPER,IGRID)
IF(IUNIT(IURES).GT.0) CALL GWF2RES7AD(KKSTP,KKPER,IGRID)
IF(IUNIT(IULPF).GT.0) CALL GWF2LPF7AD(KKPER,IGRID)
IF(IUNIT(IUHUF2).GT.0) CALL GWF2HUF7AD(KKPER,IGRID)
IF(IUNIT(IUFHB).GT.0) CALL GWF2FHB7AD(IGRID)
IF(IUNIT(IULAK).GT.0) CALL GWF2LAK7AD(KKPER,KKSTP,
1 IUNIT(IUGWT),IGRID)
if(IUNIT(IUMET).gt.0) call gwf2met1ad(igrid) ! MET
IF(IUNIT(IUMNW2).GT.0) THEN
IF (IUNIT(IUBCF6).GT.0) THEN
CALL GWF2MNW27BCF(KPER,IGRID)
ELSE IF (IUNIT(IULPF).GT.0) THEN
CALL GWF2MNW27LPF(KPER,IGRID)
ELSE IF(IUNIT(IUHUF2).GT.0) THEN
CALL GWF2MNW27HUF(KPER,IGRID)
ELSE
WRITE(IOUT,1000)
1000 FORMAT(/1X,
& '***ERROR: MNW2 PACKAGE DOES NOT SUPPORT',/,
& ' SELECTED FLOW PACKAGE',/,
& ' (MNW2 DOES FULLY SUPPORT BCF, LPF, AND HUF PACKAGES)',/,
& ' -- STOP EXECUTION')
CALL USTOP('MNW2 error-flow package')
END IF
CALL GWF2MNW27AD(KKSTP,KKPER,IGRID)
END IF
IF(IUNIT(IUMNW1).GT.0) CALL GWF2MNW17AD(IUNIT(IUBCF6),
1 IUNIT(IULPF),IUNIT(IUHUF2),IGRID)
endif
enddo ! DLT: instances
C
return
end
c ******************************************************************************
subroutine mf2005_prepareIter(retVal)
implicit none
! arguments
integer, intent(out) :: retVal
! local variables
integer iteration
logical converged
! ------------------------------
! Moved to performiter
! call mf2005_prepareIterWrp0(Iteration,converged)
! call mf2005_initIter(retVal)
retVal = 0
return
end
c =====
subroutine mf2005_prepareIterWrp0(Iteration,converged)
c get next iteration number
c 2011/06/16 renamed from mf2005_prepareIter
use m_mf2005_main
implicit none
c arguments
integer, intent(out) :: iteration ! -1: convergence failed
! 0: continue iterations
! 1: solver converged
logical, intent(in) :: converged ! .true. solver converged
! .false. solver did not converge
integer :: igrid
c ------------------------------------------------------------------------------
iteration=1 ! start value
do igrid=1,ninstance ! DLT: instances
call sgwf2ins1pnt(igrid) ! DLT: instances
call SGWF2BAS7PNT(IGRID) ! DLT: instances
kiter =kiter+1
kkiter=kiter
if (kkiter.gt.mxiter) then
! convergence failed
iteration=min(-1,iteration)
else
if (kkiter.eq.1) then
! first iteration
iteration=min(0,iteration)
else
! check convergence
if (converged) then
iteration=min(1,iteration)
else
iteration=min(0,iteration)
endif
endif
endif
enddo ! DLT: instances
return
end ! subroutine mf2005_prepareIter
c ******************************************************************************
subroutine mf2005_initIterWrp0()
! wrapper routine
implicit none
! local variables
integer :: retVal
! ------------------------------
call mf2005_initIter(retVal)
return
end
c =====
subroutine mf2005_initIter(retVal)
use m_mf2005_main
use m_mf2005_iu
implicit none
c arguments
integer , intent(out) :: retVal
c local variable
integer :: igrid
c init
retVal = 0
do igrid=1,ninstance ! DLT: instances
call sgwf2ins1pnt(igrid) ! DLT: instances
call SGWF2BAS7PNT(IGRID) ! DLT: instances
C---------INDICATE IN PRINTOUT THAT SOLUTION IS FOR HEADS
CALL UMESPR('SOLVING FOR HEAD',' ',IOUT)
WRITE(*,25)KPER,KSTP
25 FORMAT(' Solving: Stress period: ',i5,4x,
& 'Time step: ',i5,4x,'Ground-Water Flow Eqn.')
C
C7C2----ITERATIVELY FORMULATE AND SOLVE THE FLOW EQUATIONS.
c DO 30 KITER = 1, MXITER
KKITER = KITER
C
C7C2A---FORMULATE THE FINITE DIFFERENCE EQUATIONS.
CALL GWF2BAS7FM(IGRID)
if(iunit(iupwt).gt.0) call gwf2pwt3fm(kkiter,kkper,igrid,
1 iunit(iubcf6)) ! PWT3
IF(IUNIT(IUBCF6).GT.0) CALL GWF2BCF7FM(KKITER,KKSTP,
1 KKPER,IGRID)
IF(IUNIT(IULPF).GT.0) CALL GWF2LPF7FM(KKITER,
1 KKSTP,KKPER,IGRID)
IF(IUNIT(IUHUF2).GT.0) CALL GWF2HUF7FM(KKITER,
1 KKSTP,KKPER,IUNIT(IULVDA),IGRID)
IF(IUNIT(IUHFB6).GT.0) CALL GWF2HFB7FM(IGRID)
IF(IUNIT(IUWEL).GT.0) CALL GWF2WEL7FM(IGRID)
IF(IUNIT(IUDRN).GT.0) CALL GWF2DRN7FM(IGRID)
IF(IUNIT(IURIV).GT.0) CALL GWF2RIV7FM(IGRID)
IF(IUNIT(IUEVT).GT.0) THEN
IF(IUNIT(IULAK).GT.0.AND.NEVTOP.EQ.3) CALL GWF2LAK7ST(
1 0,IGRID)
CALL GWF2EVT7FM(IGRID)
IF(IUNIT(IULAK).GT.0.AND.NEVTOP.EQ.3) CALL GWF2LAK7ST(
1 1,IGRID)
END IF
IF(IUNIT(IUGHB).GT.0) CALL GWF2GHB7FM(IGRID)
if(IUNIT(IUDXC).gt.0) call gwf2dxc1fm(igrid) ! DLT: DXC added
IF(IUNIT(IURCH).GT.0) THEN
IF(IUNIT(IULAK).GT.0.AND.NRCHOP.EQ.3) CALL GWF2LAK7ST(
1 0,IGRID)
CALL GWF2RCH7FM(IGRID)
IF(IUNIT(IULAK).GT.0.AND.NRCHOP.EQ.3) CALL GWF2LAK7ST(
1 1,IGRID)
END IF
IF(IUNIT(IUFHB).GT.0) CALL GWF2FHB7FM(IGRID)
IF(IUNIT(IURES).GT.0) CALL GWF2RES7FM(IGRID)
IF(IUNIT(IUSTR).GT.0) CALL GWF2STR7FM(IGRID)
IF(IUNIT(IUIBS).GT.0) CALL GWF2IBS7FM(KKPER,IGRID)
IF(IUNIT(IUETS).GT.0) CALL GWF2ETS7FM(IGRID)
IF(IUNIT(IUDRT).GT.0) CALL GWF2DRT7FM(IGRID)
IF(IUNIT(IUUZF).GT.0) CALL GWF2UZF1FM(KKPER,KKSTP,KKITER,
1 IUNIT(IUSFR),IUNIT(IULAK),
1 IUNIT(IUCFP),IGRID)
IF(IUNIT(IUSFR).GT.0) CALL GWF2SFR7FM(KKITER,KKPER,KKSTP,
1 IUNIT(IULAK),IGRID)
IF(IUNIT(IULAK).GT.0) CALL GWF2LAK7FM(KKITER,KKPER,KKSTP,
1 IUNIT(IUSFR),IUNIT(IUUZF),
2 IGRID)
IF(IUNIT(IUMNW2).GT.0) THEN
IF (IUNIT(IUBCF6).GT.0) THEN
CALL GWF2MNW27BCF(KPER,IGRID)
ELSE IF (IUNIT(IULPF).GT.0) THEN
CALL GWF2MNW27LPF(KPER,IGRID)
ELSE IF(IUNIT(IUHUF2).GT.0) THEN
CALL GWF2MNW27HUF(KPER,IGRID)
END IF
CALL GWF2MNW27FM(KKITER,kkstp,kkper,IGRID)
END IF
IF(IUNIT(IUMNW1).GT.0) CALL GWF2MNW17FM(KKITER,
1 IUNIT(IUBCF6),IUNIT(IULPF),IUNIT(IUHUF2),IGRID)
IF(IUNIT(IUSUB).GT.0) CALL GWF2SUB7FM(KKPER,KKITER,
1 IUNIT(IUSIP),IGRID)
IF(IUNIT(IUSWT).GT.0) CALL GWF2SWT7FM(KKPER,IGRID)
c SUB-Creep
IF(IUNIT(IUSCR).GT.0) CALL GWF2SCR7FM(KKPER,KSTP,IGRID)
c SUB-Creep
if(IUNIT(IUANI).gt.0) call gwf2ani3fm(igrid) ! ANI
enddo ! DLT: instances
C
return
end
c ******************************************************************************
subroutine mf2005_performIter(retVal)
c 2011/06/16 renamed from mf2005_solve.
use m_mf2005_main
use m_mf2005_iu
implicit none
c arguments
integer, intent(out) :: retVal
c local variables
integer :: ierr
integer :: igrid
integer :: iteration
logical :: converged
c ------------------------------------------------------------------------------
c init
retVal = 0
c Moved from prepare iter (2 lines)
call mf2005_prepareIterWrp0(Iteration,converged)
call mf2005_initIter(retVal)
c
do igrid=1,ninstance ! DLT: instances
call sgwf2ins1pnt(igrid) ! DLT: instances
call SGWF2BAS7PNT(IGRID) ! DLT: instances
kkiter=kiter ! DLT: instances
C7C2B---MAKE ONE CUT AT AN APPROXIMATE SOLUTION.
IERR=0
IF (IUNIT(IUSIP).GT.0) THEN
CALL SIP7PNT(IGRID)
CALL SIP7AP(HNEW,IBOUND,CR,CC,CV,HCOF,RHS,EL,FL,GL,
1 V,W,HDCG,LRCH,NPARM,KKITER,HCLOSE,ACCL,ICNVG,
2 KKSTP,KKPER,IPCALC,IPRSIP,MXITER,NSTP(KKPER),
3 NCOL,NROW,NLAY,NODES,IOUT,0,IERR)
END IF
IF (IUNIT(IUDE4).GT.0) THEN
CALL DE47PNT(IGRID)
CALL DE47AP(HNEW,IBOUND,AU,AL,IUPPNT,IEQPNT,D4B,MXUP,
1 MXLOW,MXEQ,MXBW,CR,CC,CV,HCOF,RHS,ACCLDE4,KITER,
2 ITMX,MXITER,NITERDE4,HCLOSEDE4,IPRD4,ICNVG,NCOL,
3 NROW,NLAY,IOUT,LRCHDE4,HDCGDE4,IFREQ,KKSTP,KKPER,
4 DELT,NSTP(KKPER),ID4DIR,ID4DIM,MUTD4,
5 DELTL,NBWL,NUPL,NLOWL,NLOW,NEQ,NUP,NBW,IERR)
END IF
IF (IUNIT(IUPCG).GT.0) THEN
CALL PCG7PNT(IGRID)
CALL PCG7AP(HNEW,IBOUND,CR,CC,CV,HCOF,RHS,VPCG,SS,
1 P,CD,HCHG,LHCH,RCHG,LRCHPCG,KKITER,NITER,
2 HCLOSEPCG,RCLOSEPCG,ICNVG,KKSTP,KKPER,IPRPCG,
3 MXITER,ITER1,NPCOND,NBPOL,NSTP(KKPER),NCOL,NROW,
4 NLAY,NODES,RELAXPCG,IOUT,MUTPCG,IT1,DAMPPCG,BUFF,
5 HCSV,IERR,HPCG,DAMPPCGT,ISSFLG(KKPER),HDRY)
END IF
c IF (IUNIT(IULMG).GT.0) THEN
c CALL LMG7PNT(IGRID)
c CALL LMG7AP(HNEW,IBOUND,CR,CC,CV,HCOF,RHS,A,IA,JA,U1,
c 1 FRHS,IG,ISIZ1,ISIZ2,ISIZ3,ISIZ4,KKITER,BCLOSE,DAMPLMG,
c 2 ICNVG,KKSTP,KKPER,MXITER,MXCYC,NCOL,NROW,NLAY,NODES,
c 3 HNOFLO,IOUT,IOUTAMG,ICG,IADAMPLMG,DUPLMG,DLOWLMG)
c END IF
IF (IUNIT(42).GT.0) THEN
CALL GMG7PNT(IGRID)
CALL GMG7AP(HNEW,RHS,CR,CC,CV,HCOF,HNOFLO,IBOUND,
1 IITER,MXITER,RCLOSEGMG,HCLOSEGMG,
2 KKITER,KKSTP,KKPER,NCOL,NROW,NLAY,ICNVG,
3 SITER,TSITER,DAMPGMG,IADAMPGMG,IOUTGMG,
4 IOUT,GMGID,
5 IUNITMHC,DUP,DLOW,CHGLIMIT,
6 BIGHEADCHG,HNEWLAST)
ENDIF
IF(IERR.EQ.1) CALL USTOP(' ')
C
C7C2C---IF CONVERGENCE CRITERION HAS BEEN MET STOP ITERATING.
c IF (ICNVG.EQ.1) GOTO 33
if (icnvg.ne.1) then
solverConverged=.false.
else
solverConverged=.true.
endif
c 30 CONTINUE
c KITER = MXITER
KITER=KKITER ! DLT: instances
enddo ! DLT: instances
return
end
c ******************************************************************************
subroutine mf2005_finishIter(converged,retVal)
use m_mf2005_main
implicit none
! arguments
logical, intent(out) :: converged ! .false. not converged yet
integer, intent(out) :: retVal
c local variables
integer :: igrid
! ------------------------------
c init
converged = .true.
retVal = 0
do igrid=1,ninstance ! DLT: instances
call sgwf2ins1pnt(igrid) ! DLT: instances
converged=converged.and.solverConverged
enddo
return
end
c ******************************************************************************
subroutine mf2005_finishTimestepWrp0()
! wrapper routine
implicit none
! local variables
integer :: retVal
! ------------------------------
call mf2005_finishTimestep(retVal)
return
end
c =======
subroutine mf2005_finishTimestep(retVal)
use m_mf2005_main
use m_mf2005_iu
implicit none
c arguments
integer, intent(out) :: retVal
c local variables
integer IBDRET,ic1,ic2,ir1,ir2,il1,il2,idir
integer :: igrid
c init
retVal=0
do igrid=1,ninstance ! DLT: instances
call sgwf2ins1pnt(igrid) ! DLT: instances
call SGWF2BAS7PNT(IGRID) ! DLT: instances
timeStepCalculated=.true. ! DLT: instances
C
c 33 CONTINUE
C
C7C3----DETERMINE WHICH OUTPUT IS NEEDED.
CALL GWF2BAS7OC(KKSTP,KKPER,ICNVG,IUNIT(IUOC),IGRID)
C
C7C4----CALCULATE BUDGET TERMS. SAVE CELL-BY-CELL FLOW TERMS.
MSUM = 1
IF (IUNIT(IUBCF6).GT.0) THEN
CALL GWF2BCF7BDS(KKSTP,KKPER,IGRID)
CALL GWF2BCF7BDCH(KKSTP,KKPER,IGRID)
IBDRET=0
IC1=1
IC2=NCOL
IR1=1
IR2=NROW
IL1=1
IL2=NLAY
DO 37 IDIR = 1, 3
CALL GWF2BCF7BDADJ(KKSTP,KKPER,IDIR,IBDRET,
1 IC1,IC2,IR1,IR2,IL1,IL2,IGRID)
37 CONTINUE
ENDIF
IF(IUNIT(IULPF).GT.0) THEN
CALL GWF2LPF7BDS(KKSTP,KKPER,IGRID)
CALL GWF2LPF7BDCH(KKSTP,KKPER,IGRID)
IBDRET=0
IC1=1
IC2=NCOL
IR1=1
IR2=NROW
IL1=1
IL2=NLAY
DO 157 IDIR=1,3
CALL GWF2LPF7BDADJ(KKSTP,KKPER,IDIR,IBDRET,
& IC1,IC2,IR1,IR2,IL1,IL2,IGRID)
157 CONTINUE
ENDIF
IF(IUNIT(IUHUF2).GT.0) THEN
CALL GWF2HUF7BDS(KKSTP,KKPER,IGRID)
CALL GWF2HUF7BDCH(KKSTP,KKPER,IUNIT(IULVDA),IGRID)
IBDRET=0
IC1=1
IC2=NCOL
IR1=1
IR2=NROW
IL1=1
IL2=NLAY
DO 159 IDIR=1,3
CALL GWF2HUF7BDADJ(KKSTP,KKPER,IDIR,IBDRET,
& IC1,IC2,IR1,IR2,IL1,IL2,IUNIT(IULVDA),IGRID)
159 CONTINUE
ENDIF
IF(IUNIT(IUWEL).GT.0) CALL GWF2WEL7BD(KKSTP,KKPER,IGRID)
IF(IUNIT(IUDRN).GT.0) CALL GWF2DRN7BD(KKSTP,KKPER,IGRID)
IF(IUNIT(IURIV).GT.0) CALL GWF2RIV7BD(KKSTP,KKPER,IGRID)
IF(IUNIT(IUEVT).GT.0) THEN
IF(IUNIT(IULAK).GT.0.AND.NEVTOP.EQ.3) CALL GWF2LAK7ST(
1 0,IGRID)
CALL GWF2EVT7BD(KKSTP,KKPER,IGRID)
IF(IUNIT(IULAK).GT.0.AND.NEVTOP.EQ.3) CALL GWF2LAK7ST(
1 1,IGRID)
END IF
IF(IUNIT(IUGHB).GT.0) CALL GWF2GHB7BD(KKSTP,KKPER,IGRID)
if(IUNIT(IUDXC).gt.0) call gwf2dxc1bd(kkstp,kkper,igrid)
IF(IUNIT(IURCH).GT.0) THEN
IF(IUNIT(IULAK).GT.0.AND.NRCHOP.EQ.3) CALL GWF2LAK7ST(
1 0,IGRID)
CALL GWF2RCH7BD(KKSTP,KKPER,IGRID)
IF(IUNIT(IULAK).GT.0.AND.NRCHOP.EQ.3) CALL GWF2LAK7ST(
1 1,IGRID)
END IF
IF(IUNIT(IUFHB).GT.0) CALL GWF2FHB7BD(KKSTP,KKPER,IGRID)
IF(IUNIT(IURES).GT.0) CALL GWF2RES7BD(KKSTP,KKPER,IGRID)
IF(IUNIT(IUSTR).GT.0) CALL GWF2STR7BD(KKSTP,KKPER,IGRID)
IF(IUNIT(IUIBS).GT.0) CALL GWF2IBS7BD(KKSTP,KKPER,IGRID)
IF(IUNIT(IUETS).GT.0) CALL GWF2ETS7BD(KKSTP,KKPER,IGRID)
IF(IUNIT(IUDRT).GT.0) CALL GWF2DRT7BD(KKSTP,KKPER,IGRID)
IF(IUNIT(IUUZF).GT.0) CALL GWF2UZF1BD(KKSTP,KKPER,
1 IUNIT(IULAK),IGRID)
IF(IUNIT(IUSFR).GT.0) CALL GWF2SFR7BD(KKSTP,KKPER,
1 IUNIT(IUGWT),IUNIT(IULAK),IUNIT(IUGAGE),
1 IUNIT(IUUZF),NSOL,IGRID)
IF(IUNIT(IULAK).GT.0) CALL GWF2LAK7BD(KKSTP,KKPER,
1 IUNIT(IUGWT),IUNIT(IUGAGE),IUNIT(IUSFR),
1 IUNIT(IUUZF),NSOL,IGRID)
IF(IUNIT(IUMNW2).GT.0) CALL GWF2MNW27BD(KKSTP,KKPER,IGRID)
IF(IUNIT(IUMNW1).GT.0) CALL GWF2MNW17BD(NSTP(KPER),KKSTP,
1 KKPER,IGRID)
IF(IUNIT(IUSUB).GT.0) CALL GWF2SUB7BD(KKSTP,KKPER,IGRID)
IF(IUNIT(IUSWT).GT.0) CALL GWF2SWT7BD(KKSTP,KKPER,IGRID)
IF(IUNIT(IUSCR).GT.0) CALL GWF2SCR7BD(KKSTP,KKPER,IGRID)
CLMT
CLMT----CALL LINK-MT3DMS SUBROUTINES TO SAVE FLOW-TRANSPORT LINK FILE
CLMT----FOR USE BY MT3DMS FOR TRANSPORT SIMULATION
CLMT
INCLUDE 'lmt7.inc'
CLMT
C
C Observation and hydrograph simulated equivalents
CALL OBS2BAS7SE(IUNIT(IUHOB),IGRID)
IF(IUNIT(IUDROB).GT.0) CALL OBS2DRN7SE(IGRID)
IF(IUNIT(IURVOB).GT.0) CALL OBS2RIV7SE(IGRID)
IF(IUNIT(IUGBOB).GT.0) CALL OBS2GHB7SE(IGRID)
IF(IUNIT(IUSTOB).GT.0) CALL OBS2STR7SE(IGRID)
IF(IUNIT(IUCHOB).GT.0) CALL OBS2CHD7SE(KKPER,IGRID)
IF(IUNIT(IUHYD).GT.0) CALL GWF2HYD7BAS7SE(1,IGRID)
IF(IUNIT(IUHYD).GT.0 .AND. IUNIT(IUIBS).GT.0)
1 CALL GWF2HYD7IBS7SE(1,IGRID)
IF(IUNIT(IUHYD).GT.0 .AND. IUNIT(IUSUB).GT.0)
1 CALL GWF2HYD7SUB7SE(1,IGRID)
IF(IUNIT(IUHYD).GT.0 .AND. IUNIT(IUSTR).GT.0)
1 CALL GWF2HYD7STR7SE(1,IGRID)
IF(IUNIT(IUHYD).GT.0 .AND. IUNIT(IUSFR).GT.0)
1 CALL GWF2HYD7SFR7SE(1,IGRID)
C
C7C5---PRINT AND/OR SAVE DATA.
CALL GWF2BAS7OT(KKSTP,KKPER,ICNVG,1,IGRID)
IF(IUNIT(IUIBS).GT.0) CALL GWF2IBS7OT(KKSTP,KKPER,
1 IUNIT(IUIBS),IGRID)
IF(IUNIT(IUHUF2).GT.0)THEN
IF(IOHUFHDS .NE.0 .OR.IOHUFFLWS .NE.0)
1 CALL GWF2HUF7OT(KKSTP,KKPER,ICNVG,1,IGRID)
ENDIF
IF(IUNIT(IUMNWI).NE.0) CALL GWF2MNW2I7OT(NSTP(KKPER),KKSTP,
1 KKPER,IGRID)
IF(IUNIT(IUSUB).GT.0) CALL GWF2SUB7OT(KKSTP,KKPER,
1 IUNIT(IUSUB),IGRID)
IF(IUNIT(IUSWT).GT.0) CALL GWF2SWT7OT(KKSTP,KKPER,IGRID)
c SUB-Creep
IF(IUNIT(IUSCR).GT.0) CALL GWF2SCR7OT(KKSTP,KKPER,IGRID)
c SUB-Creep end
IF(IUNIT(IUHYD).GT.0) CALL GWF2HYD7BAS7OT(KKSTP,KKPER,IGRID)
C
C7C6---JUMP TO END OF PROGRAM IF CONVERGENCE WAS NOT ACHIEVED.
c IF(ICNVG.EQ.0) GO TO 110
C
call splitfiles(iout,igrid) ! DLT
C-----END OF TIME STEP (KSTP) AND STRESS PERIOD (KPER) LOOPS
c 90 CONTINUE
c 100 CONTINUE
enddo ! DLT: instances
return
end
c ******************************************************************************
subroutine mf2005_finishSimulationWrp0()
! wrapper routine
implicit none
! local variables
integer :: retVal
! ------------------------------
call mf2005_finishSimulation(retVal)
return
end
c =======
subroutine mf2005_finishSimulation(retVal)
use m_mf2005_main
use m_mf2005_iu
implicit none
c arguments
integer, intent(out) :: retVal
c local variable
integer :: igrid
c init
retVal = 0
do igrid=1,ninstance ! DLT: instances
call sgwf2ins1pnt(igrid) ! DLT: instances
call SGWF2BAS7PNT(IGRID) ! DLT: instances
C
C
IF(IUNIT(IUMNW1).NE.0) CALL GWF2MNW17OT(IGRID)
C
C8------END OF SIMULATION
C-------SAVE RESTART RECORDS FOR SUB PACKAGE
110 IF(IUNIT(IUSUB).GT.0) CALL GWF2SUB7SV(IGRID)
C
C Observation output
IF(IUNIT(IUHOB).GT.0) CALL OBS2BAS7OT(IUNIT(IUHOB),IGRID)
IF(IUNIT(IUDROB).GT.0) CALL OBS2DRN7OT(IGRID)
IF(IUNIT(IURVOB).GT.0) CALL OBS2RIV7OT(IGRID)
IF(IUNIT(IUGBOB).GT.0) CALL OBS2GHB7OT(IGRID)
IF(IUNIT(IUSTOB).GT.0) CALL OBS2STR7OT(IGRID)
IF(IUNIT(IUCHOB).GT.0) CALL OBS2CHD7OT(IGRID)
CALL GLO1BAS6ET(IOUT,IBDT,1)
C
C9------CLOSE FILES AND DEALLOCATE MEMORY. GWF2BAS7DA MUST BE CALLED
C9------LAST BECAUSE IT DEALLOCATES IUNIT.
CALL SGWF2BAS7PNT(IGRID)
IF(IUNIT(IUBCF6).GT.0) CALL GWF2BCF7DA(IGRID)
IF(IUNIT(IUWEL).GT.0) CALL GWF2WEL7DA(IGRID)
IF(IUNIT(IUDRN).GT.0) CALL GWF2DRN7DA(IGRID)
IF(IUNIT(IURIV).GT.0) CALL GWF2RIV7DA(IGRID)
IF(IUNIT(IUEVT).GT.0) CALL GWF2EVT7DA(IGRID)
IF(IUNIT(IUGHB).GT.0) CALL GWF2GHB7DA(IGRID)
IF(IUNIT(IURCH).GT.0) CALL GWF2RCH7DA(IGRID)
IF(IUNIT(IUSIP).GT.0) CALL SIP7DA(IGRID)
IF(IUNIT(IUDE4).GT.0) CALL DE47DA(IGRID)
IF(IUNIT(IUPCG).GT.0) CALL PCG7DA(IGRID)
c IF(IUNIT(IULMG).GT.0) CALL LMG7DA(IGRID)
IF(IUNIT(IUFHB).GT.0) CALL GWF2FHB7DA(IGRID)
IF(IUNIT(IURES).GT.0) CALL GWF2RES7DA(IGRID)
IF(IUNIT(IUSTR).GT.0) CALL GWF2STR7DA(IGRID)
IF(IUNIT(IUIBS).GT.0) CALL GWF2IBS7DA(IGRID)
IF(IUNIT(IUCHD).GT.0) CALL GWF2CHD7DA(IGRID)
IF(IUNIT(IUHFB6).GT.0) CALL GWF2HFB7DA(IGRID)
IF(IUNIT(IULAK).GT.0 .OR. IUNIT(IUSFR).GT.0)
1 CALL GWF2LAK7DA(IUNIT(IULAK),IGRID)
IF(IUNIT(IULPF).GT.0) CALL GWF2LPF7DA(IGRID)
IF(IUNIT(IUHUF2).GT.0) CALL GWF2HUF7DA(IGRID)
IF(IUNIT(IUETS).GT.0) CALL GWF2ETS7DA(IGRID)
IF(IUNIT(IUDRT).GT.0) CALL GWF2DRT7DA(IGRID)
IF(IUNIT(42).GT.0) CALL GMG7DA(IGRID)
IF(IUNIT(IUSFR).GT.0) CALL GWF2SFR7DA(IGRID)
IF(IUNIT(IUGAGE).GT.0) CALL GWF2GAG7DA(IGRID)
IF(IUNIT(IUMNW2).GT.0) CALL GWF2MNW27DA(IGRID)
IF(IUNIT(IUMNWI).GT.0) CALL GWF2MNW2I7DA(IGRID)
IF(IUNIT(IUMNW1).GT.0) CALL GWF2MNW17DA(IGRID)
IF(IUNIT(IUSUB).GT.0) CALL GWF2SUB7DA(IGRID)
IF(IUNIT(IUUZF).GT.0) CALL GWF2UZF1DA(IGRID)
IF(IUNIT(IUSWT).GT.0) CALL GWF2SWT7DA(IGRID)
IF(IUNIT(IUSCR).GT.0) CALL GWF2SCR7DA(IGRID)
CALL OBS2BAS7DA(IUNIT(IUHOB),IGRID)
IF(IUNIT(IUDROB).GT.0) CALL OBS2DRN7DA(IGRID)
IF(IUNIT(IURVOB).GT.0) CALL OBS2RIV7DA(IGRID)
IF(IUNIT(IUGBOB).GT.0) CALL OBS2GHB7DA(IGRID)
IF(IUNIT(IUSTOB).GT.0) CALL OBS2STR7DA(IGRID)
IF(IUNIT(IUCHOB).GT.0) CALL OBS2CHD7DA(IGRID)
IF(IUNIT(IUHYD).GT.0) CALL GWF2HYD7DA(IGRID)
if(IUNIT(IUANI).gt.0) call gwf2ani3da(igrid) ! ANI
if(IUNIT(IUMET).gt.0) call gwf2met1da(igrid) ! MET
CALL GWF2BAS7DA(IGRID)
C
C10-----END OF PROGRAM.
IF(ICNVG.EQ.0) THEN
WRITE(*,*) 'FAILED TO MEET SOLVER CONVERGENCE CRITERIA'
retVal = -1
ELSE
WRITE(*,*) ' Normal termination of simulation'
END IF
call sgwf2ins1da(igrid)
c CALL USTOP(' ')
C
enddo ! DLT: instances
return
END
SUBROUTINE GETNAMFIL(FNAME)
C ******************************************************************
C GET THE NAME OF THE NAME FILE
C ******************************************************************
C SPECIFICATIONS:
C
C ------------------------------------------------------------------
CHARACTER*(*) FNAME
CHARACTER*200 COMLIN
LOGICAL EXISTS
C ------------------------------------------------------------------
C
C Get name file from command line or user interaction.
FNAME=' '
COMLIN=' '
C *** Subroutines GETARG and GETCL are extensions to Fortran 90/95 that
C *** allow a program to retrieve command-line arguments. To enable
C *** Modflow-2000 to read the name of a Name file from the command
C *** line, either GETARG or GETCL must be called, but not both. As
C *** distributed, the call to GETARG is uncommented. For compilers
C *** that support GETCL but not GETARG, comment out the call to GETARG
C *** and uncomment the call to GETCL. The calls to both GETARG and
C *** GETCL may be commented out for compilers that do not support
C *** either extension.
CALL GETARG(1,COMLIN)
C CALL GETCL(COMLIN)
ICOL = 1
IF(COMLIN.NE.' ') THEN
FNAME=COMLIN
ELSE
15 WRITE (*,*) ' Enter the name of the NAME FILE: '
READ (*,'(A)') FNAME
CALL URWORD(FNAME,ICOL,ISTART,ISTOP,0,N,R,0,0)
FNAME=FNAME(ISTART:ISTOP)
IF (FNAME.EQ.' ') GOTO 15
ENDIF
INQUIRE (FILE=FNAME,EXIST=EXISTS)
IF(.NOT.EXISTS) THEN
NC=INDEX(FNAME,' ')
FNAME(NC:NC+3)='.nam'
INQUIRE (FILE=FNAME,EXIST=EXISTS)
IF(.NOT.EXISTS) THEN
WRITE (*,480) FNAME(1:NC-1),FNAME(1:NC+3)
480 FORMAT(1X,'Can''t find name file ',A,' or ',A)
CALL USTOP(' ')
ENDIF
ENDIF
C
RETURN
END
SUBROUTINE GLO1BAS6ET(IOUT,IBDT,IPRTIM)
C ******************************************************************
C Get end time and calculate elapsed time
C ******************************************************************
C
C SPECIFICATIONS:
C ------------------------------------------------------------------
INTEGER IBDT(8), IEDT(8), IDPM(12)
DATA IDPM/31,28,31,30,31,30,31,31,30,31,30,31/ ! Days per month
DATA NSPD/86400/ ! Seconds per day
C ------------------------------------------------------------------
C
C Get current date and time, assign to IEDT, and write.
CALL DATE_AND_TIME(VALUES=IEDT)
WRITE(*,1000) (IEDT(I),I=1,3),(IEDT(I),I=5,7)
1000 FORMAT(1X,'Run end date and time (yyyy/mm/dd hh:mm:ss): ',
&I4,'/',I2.2,'/',I2.2,1X,I2,':',I2.2,':',I2.2)
IF(IPRTIM.GT.0) THEN
WRITE(IOUT,'(1X)')
WRITE(IOUT,1000) (IEDT(I),I=1,3),(IEDT(I),I=5,7)
END IF
C
C Calculate elapsed time in days and seconds
NDAYS=0
LEAP=0
IF (MOD(IEDT(1),4).EQ.0) LEAP = 1
IBD = IBDT(3) ! BEGIN DAY
IED = IEDT(3) ! END DAY
C FIND DAYS
IF (IBDT(2).NE.IEDT(2)) THEN
C MONTHS DIFFER
MB = IBDT(2) ! BEGIN MONTH
ME = IEDT(2) ! END MONTH
NM = ME-MB+1 ! NUMBER OF MONTHS TO LOOK AT
IF (MB.GT.ME) NM = NM+12
MC=MB-1
DO 10 M=1,NM
MC=MC+1 ! MC IS CURRENT MONTH
IF (MC.EQ.13) MC = 1
IF (MC.EQ.MB) THEN
NDAYS = NDAYS+IDPM(MC)-IBD
IF (MC.EQ.2) NDAYS = NDAYS + LEAP
ELSEIF (MC.EQ.ME) THEN
NDAYS = NDAYS+IED
ELSE
NDAYS = NDAYS+IDPM(MC)
IF (MC.EQ.2) NDAYS = NDAYS + LEAP
ENDIF
10 CONTINUE
ELSEIF (IBD.LT.IED) THEN
C START AND END IN SAME MONTH, ONLY ACCOUNT FOR DAYS
NDAYS = IED-IBD
ENDIF
ELSEC=NDAYS*NSPD
C
C ADD OR SUBTRACT SECONDS
ELSEC = ELSEC+(IEDT(5)-IBDT(5))*3600.0
ELSEC = ELSEC+(IEDT(6)-IBDT(6))*60.0
ELSEC = ELSEC+(IEDT(7)-IBDT(7))
ELSEC = ELSEC+(IEDT(8)-IBDT(8))*0.001
C
C CONVERT SECONDS TO DAYS, HOURS, MINUTES, AND SECONDS
NDAYS = ELSEC/NSPD
RSECS = MOD(ELSEC,86400.0)
NHOURS = RSECS/3600.0
RSECS = MOD(RSECS,3600.0)
NMINS = RSECS/60.0
RSECS = MOD(RSECS,60.0)
NSECS = RSECS
RSECS = MOD(RSECS,1.0)
MSECS = NINT(RSECS*1000.0)
NRSECS = NSECS
IF (RSECS.GE.0.5) NRSECS=NRSECS+1
C
C Write elapsed time to screen
IF (NDAYS.GT.0) THEN
WRITE(*,1010) NDAYS,NHOURS,NMINS,NRSECS
1010 FORMAT(1X,'Elapsed run time: ',I3,' Days, ',I2,' Hours, ',I2,
& ' Minutes, ',I2,' Seconds',/)
ELSEIF (NHOURS.GT.0) THEN
WRITE(*,1020) NHOURS,NMINS,NRSECS
1020 FORMAT(1X,'Elapsed run time: ',I2,' Hours, ',I2,
& ' Minutes, ',I2,' Seconds',/)
ELSEIF (NMINS.GT.0) THEN
WRITE(*,1030) NMINS,NSECS,MSECS
1030 FORMAT(1X,'Elapsed run time: ',I2,' Minutes, ',
& I2,'.',I3.3,' Seconds',/)
ELSE
WRITE(*,1040) NSECS,MSECS
1040 FORMAT(1X,'Elapsed run time: ',I2,'.',I3.3,' Seconds',/)
ENDIF
C
C Write times to file if requested
IF(IPRTIM.GT.0) THEN
IF (NDAYS.GT.0) THEN
WRITE(IOUT,1010) NDAYS,NHOURS,NMINS,NRSECS
ELSEIF (NHOURS.GT.0) THEN
WRITE(IOUT,1020) NHOURS,NMINS,NRSECS
ELSEIF (NMINS.GT.0) THEN
WRITE(IOUT,1030) NMINS,NSECS,MSECS
ELSE
WRITE(IOUT,1040) NSECS,MSECS
ENDIF
ENDIF
C
RETURN
END
c ******************************************************************************
function sutl_getTimeStepLength(igrid)
c description:
c ------------------------------------------------------------------------------
c get the timesteplength in days of the current timestep of model igrid
c
c declaration section
c ------------------------------------------------------------------------------
use m_mf2005_main, only: GWFBASDAT,GLOBALDAT,mi
implicit none
c function declaration
double precision :: sutl_getTimeStepLength ! return value: >0: time step length in days
! <=0: no more timesteps left
c arguments
integer, intent(in) :: igrid !> grid number of modflow
c local variables
double precision :: dfact
logical :: lastStep
integer :: lkper,lkstp,gnper,gnstp,tkper
c program section
c ------------------------------------------------------------------------------
! check or any timesteps are left
lastStep=.false.
lkper=mi(igrid)%kper
lkstp=mi(igrid)%kstp
gnper=GLOBALDAT(igrid)%nper
tkper=min(max(1,lkper),gnper) ! to be sure stressperiod number in interval [1,nper]
gnstp=GLOBALDAT(igrid)%nstp(tkper)
if (lkper.gt.gnper ) lastStep=.true.
if (lkper.eq.gnper .and. lkstp.gt.gnstp) lastStep=.true.
if (lastStep) then
! no more timesteps left
sutl_getTimeStepLength = -1.0d0
else
! get conversion factor from model time to days
select case( GLOBALDAT(igrid)%itmuni )
case (1) ! seconds
dfact=1.0d0/86400.d0
case (2) ! minutes
dfact=1.0d0/1440.d0
case (3) ! hours
dfact=1.0d0/24.d0
case (4) ! days
dfact=1.0d0
case (5) ! years
dfact=365.d0
case default ! unknown
dfact=1.0d0
end select
! assign functionvalue
sutl_getTimeStepLength = dfact*GWFBASDAT(igrid)%DELT
endif
c end of program
return
end
logical function mf2005_lastTimeStep(igrid)
c description:
c ------------------------------------------------------------------------------
c check is this was the last timestep
c
c declaration section
c ------------------------------------------------------------------------------
use m_mf2005_main, only: GWFBASDAT,GLOBALDAT,mi
implicit none
c arguments
integer, intent(in) :: igrid !> grid number of modflow
c local variables
logical :: lastStep
integer :: lkper,lkstp,gnper,gnstp,tkper
c program section
c ------------------------------------------------------------------------------
lastStep=.false.
lkper=mi(igrid)%kper
lkstp=mi(igrid)%kstp
gnper=GLOBALDAT(igrid)%nper
tkper=min(max(1,lkper),gnper) ! to be sure stressperiod number in interval [1,nper]
gnstp=GLOBALDAT(igrid)%nstp(tkper)
if (lkper.gt.gnper ) then
lastStep=.true.
endif
if (lkper.eq.gnper .and. lkstp.ge.gnstp) then
lastStep=.true.
endif
mf2005_lastTimeStep = lastStep
return
end
!> Return number of MODFLOW grids.
logical function mf2005_PutNumberOfGrids(nGrids)
!... modules
use m_mf2005_main, only: ninstance
implicit none
!... arguments
integer, intent(out) :: nGrids
!... locals
logical :: ok
!.......................................................................
nGrids = ninstance
ok = .true.
if (nGrids.le.0) ok = .false.
mf2005_PutNumberOfGrids = ok
end function
!> return dimensions of the MODFLOW grid.
logical function mf2005_PutGridDimensions(igrid,nRows,nColumns,
1 nLayers)
!... modules
use global, only: ncol, nrow, nlay
implicit none
!... arguments
integer, intent(in) :: igrid
integer, intent(out) :: nRows
integer, intent(out) :: nColumns
integer, intent(out) :: nLayers
!... locals
logical :: ok
!.......................................................................
!... get pointers
call sgwf2bas7pnt(igrid)
!... checks
ok = .true.
if (.not.associated(nrow)) then
ok = .false.
else
if (nrow.le.0) ok = .false.
end if
if (.not.associated(ncol)) then
ok = .false.
else
if (ncol.le.0) ok = .false.
end if
if (.not.associated(nlay)) then
ok = .false.
else
if (ncol.le.0) ok = .false.
end if
if (ok) then
nRows = nrow
nColumns = ncol
nLayers = nlay
end if
mf2005_PutGridDimensions = ok
end function
!> Return number of exchange items (IDs).
logical function mf2005_PutModSimNumberOfIDs(igrid, nxch)
!... modules
use gwfdxcmodule, only: ndxc
implicit none
!... arguments
integer, intent(in) :: igrid
integer, intent(out) :: nxch
!... locals
logical :: ok
!.......................................................................
!... get pointers
call sgwf2dxc1pnt(igrid) !picks up ndxc
!... check
ok = .true.
if (.not.associated(ndxc)) then
ok = .false.
mf2005_PutModSimNumberOfIDs = ok
return
end if
nxch = ndxc
if (nxch.le.0) ok = .false.
mf2005_PutModSimNumberOfIDs = ok
end function
!> Return number of exchange items (IDs).
logical function mf2005_PutModRibaNumberOfIDs(igrid, nxch)
!... modules
use gwfdxcmodule, only: ndxc
implicit none
!... arguments
integer, intent(in) :: igrid
integer, intent(out) :: nxch
!... locals
logical :: ok
!.......................................................................
!... get pointers
call sgwf2dxc1pnt(igrid) !picks up ndxc
!... check
ok = .true.
if (.not.associated(ndxc)) then
ok = .false.
mf2005_PutModRibaNumberOfIDs = ok
return
end if
nxch = ndxc
if (nxch.le.0) ok = .false.
mf2005_PutModRibaNumberOfIDs = ok
end function
!> Return MODFLOW exchange IDs.
logical function mf2005_PutModSimIDs(igrid,ids)
!... modules
use gwfdxcmodule, only: dxcid, ndxc
implicit none
!... arguments
integer, intent(in) :: igrid
integer, dimension(*), intent(out) :: ids
!... locals
logical :: ok
integer :: i
!.......................................................................
!... set pointers
call sgwf2dxc1pnt(igrid)
!... check
ok = .true.
if (.not.associated(dxcid)) then
ok = .false.
mf2005_PutModSimIDs = ok
return
end if
!... Copy the IDs
do i = 1, ndxc
ids(i) = dxcid(i)
end do
mf2005_PutModSimIDs = ok
end function
!> Return MODFLOW exchange IDs.
logical function mf2005_PutModRibaIDs(igrid,ids)
!... modules
use gwfdxcmodule, only: dxcid, ndxc
implicit none
!... arguments
integer, intent(in) :: igrid
integer, dimension(*), intent(out) :: ids
!... locals
logical :: ok
integer :: i
!.......................................................................
!... set pointers
call sgwf2dxc1pnt(igrid)
!... check
ok = .true.
if (.not.associated(dxcid)) then
ok = .false.
mf2005_PutModRibaIDs = ok
return
end if
!... Copy the IDs
do i = 1, ndxc
ids(i) = dxcid(i)
end do
mf2005_PutModRibaIDs = ok
end function
!> return exchange MODFLOW cells (layer, row, column)
logical function mf2005_PutModSimCells(igrid,cells)
!... modules
use gwfdxcmodule, only: ndxc, dxcil, dxcir, dxcic
implicit none
!... arguments
integer, intent(in) :: igrid
integer, dimension(3,*), intent(out) :: cells
!... locals
logical :: ok
integer :: i
!.......................................................................
!... set pointers
call sgwf2dxc1pnt(igrid)
!... check
ok = .true.
if (.not.associated(ndxc)) ok = .false.
if (.not.associated(dxcil)) ok = .false.
if (.not.associated(dxcir)) ok = .false.
if (.not.associated(dxcic)) ok = .false.
if (.not.ok) then
mf2005_PutModSimCells = ok
return
end if
!... copy cells
do i = 1, ndxc
cells(1,i) = dxcil(i)
cells(2,i) = dxcir(i)
cells(3,i) = dxcic(i)
end do
mf2005_PutModSimCells = ok
end function
!> return exchange MODFLOW cells (layer, row, column)
logical function mf2005_PutModRibaCells(igrid,cells)
!... modules
use gwfdxcmodule, only: ndxc, dxcil, dxcir, dxcic
implicit none
!... arguments
integer, intent(in) :: igrid
integer, dimension(3,*), intent(out) :: cells
!... locals
logical :: ok
integer :: i
!.......................................................................
!... set pointers
call sgwf2dxc1pnt(igrid)
!... check
ok = .true.
if (.not.associated(ndxc)) ok = .false.
if (.not.associated(dxcil)) ok = .false.
if (.not.associated(dxcir)) ok = .false.
if (.not.associated(dxcic)) ok = .false.
if (.not.ok) then
mf2005_PutModRibaCells = ok
return
end if
!... copy cells
do i = 1, ndxc
cells(1,i) = dxcil(i)
cells(2,i) = dxcir(i)
cells(3,i) = dxcic(i)
end do
mf2005_PutModRibaCells = ok
end function
!> return exchange MODFLOW cells (layer, row, column)
logical function mf2005_PutModMozCells(igrid,cells)
!... modules
use gwfdxcmodule, only: ndxclsw, dxcirlsw, dxciclsw
implicit none
!... arguments
integer, intent(in) :: igrid
integer, dimension(3,*), intent(out) :: cells
!... locals
logical :: ok
integer :: i
!.......................................................................
!... set pointers
call sgwf2dxc1pnt(igrid)
!... check
ok = .true.
if (.not.associated(ndxclsw)) ok = .false.
if (.not.associated(dxcirlsw)) ok = .false.
if (.not.associated(dxciclsw)) ok = .false.
if (.not.ok) then
mf2005_PutModMozCells = ok
return
end if
!... copy cells
do i = 1, ndxclsw
cells(1,i) = 1
cells(2,i) = dxcirlsw(i)
cells(3,i) = dxciclsw(i)
end do
mf2005_PutModMozCells = ok
end function
!> Return steady-state flag.
logical function mf2005_PutSimulationType(igrid, lss)
!... modules
use global, only: nper, issflg
implicit none
!... arguments
integer, intent(in) :: igrid
logical, intent(out) :: lss
!... locals
logical :: ok
integer :: i
!.......................................................................
!... get pointers
call sgwf2bas7pnt(igrid)
!... check
ok = .true.
if (.not.associated(nper)) then
ok = .false.
else
if (nper.le.0) ok = .false.
end if
if (.not.associated(issflg)) ok = .false.
if (.not.ok) then
mf2005_PutSimulationType = ok
return
end if
!... find out or model is steady state or not
lss = .true.
do i=1, nper
if (issflg(i).eq.0) lss = .false.
enddo
mf2005_PutSimulationType = ok
end function
!> Return flag for LPF activation.
logical function mf2005_PutLPFActive(igrid, llpf)
!... modules
use global, only: iunit
use m_mf2005_iu, only: iulpf
implicit none
!... arguments
integer, intent(in) :: igrid
logical, intent(out) :: llpf
!... locals
logical :: ok
integer :: i
!.......................................................................
!... get pointers
call sgwf2bas7pnt(igrid)
llpf = .false.
if(IUNIT(IULPF).gt.0) llpf = .true.
ok = .true.
mf2005_PutLPFActive = ok
end function
!> Return flag for LPF activation.
logical function mf2005_PutPWTActive(igrid, lpwt)
!... modules
use global, only: iunit
use m_mf2005_iu, only: iupwt
implicit none
!... arguments
integer, intent(in) :: igrid
logical, intent(out) :: lpwt
!... locals
logical :: ok
integer :: i
!.......................................................................
!... get pointers
call sgwf2bas7pnt(igrid)
lpwt = .false.
if(iunit(iupwt).gt.0) lpwt = .true.
ok = .true.
mf2005_PutPWTActive = ok
end function
!> Return hnoflo
logical function mf2005_PutHeadNoFlo(igrid, h)
!... modules
use gwfbasmodule, only: hnoflo
implicit none
!... arguments
integer, intent(in) :: igrid
real, intent(out) :: h
!... locals
logical :: ok
integer :: i
!.......................................................................
!... get pointers
call sgwf2bas7pnt(igrid)
h = hnoflo
mf2005_PutHeadNoFlo = .true.
end function
logical function mf2005_PutHeads(igrid,iliric,n,head,mv)
!... modules
use global, only: ibound, hnew
implicit none
!... arguments
integer, intent(in) :: igrid, n
integer, dimension(3,n), intent(in) :: iliric
real, intent(in) :: mv
real, dimension(n), intent(out) :: head
!... locals
integer :: i, icol, irow, ilay
! get pointers
call sgwf2bas7pnt(igrid)
do i = 1, n
ilay = iliric(1,i)
irow = iliric(2,i)
icol = iliric(3,i)
if (ibound(icol,irow,ilay).ne.0) then
head(i) = hnew(icol,irow,ilay)
else
head(i) = mv
endif
end do
mf2005_PutHeads = .true.
end function
logical function mf2005_PutHeadsForLayer(head,ncol,nrow,
1 ilay,igrid)
!... modules
use global, only: hnew
implicit none
!... arguments
integer, intent(in) :: ncol,nrow,ilay,igrid
double precision, dimension(ncol,nrow), intent(out) :: head
!... locals
! get pointers
call sgwf2bas7pnt(igrid)
head = hnew(:,:,ilay)
mf2005_PutHeadsForLayer = .true.
end function mf2005_PutHeadsForLayer
logical function mf2005_GetRecharge(recharge,ncol,nrow,igrid)
!... modules
use global, only: iunit,delr,delc
use m_mf2005_iu, only: iurch
use gwfrchmodule, only: rechbuff
!... arguments
integer, intent(in) :: ncol,nrow,igrid
real, dimension(ncol,nrow), intent(in) :: recharge
!... locals
!.......................................................................
! check if package is active
if (iunit(iurch).le.0) then
mf2005_GetRecharge = .false.
return
end if
! get pointers
call sgwf2rch7pnt(igrid)
! allocate for the first time
if (.not.associated(rechbuff)) then
allocate(rechbuff(ncol,nrow))
end if
! set and multipy with cell area
do irow=1,nrow
do icol=1,ncol
rechbuff(icol,irow)=
1 recharge(icol,irow)*delr(icol)*delc(irow)
end do
end do
! set pointers
call sgwf2rch7psv(igrid)
mf2005_GetRecharge = .true.
end function mf2005_GetRecharge
!modflow-ribasim
logical function mf2005_GetQdemand(igrid,nid,qdemand,xchIdx,
& xchOff,mv)
!... modules
use gwfbasmodule, only: delt
use gwfdxcmodule, only: dxcuzflux,dxcqdemand
implicit none
! arguments
integer, intent(in) :: igrid
integer, intent(in) :: nid
real, dimension(*), intent(in) :: qdemand
integer, dimension(*), intent(in) :: xchIdx
integer, dimension(nid), intent(in) :: xchOff
real, intent(in) :: mv
!... locals
integer :: i, j, js, je, k, ilay, irow, icol
real :: q
!......................................................................
! get pointers
call sgwf2bas7pnt(igrid) !So this picks up delt
c call sgwf2dxc1pnt(igrid) !So this picks up dxcqdemand, which is not necessary because we are calculating it in this subroutine
dxcuzflux = 0.0 !Should not be necessary (at least not here), but otherwise this array is not initialized and we get very big negative unsat. zone fluxes at the ID locations
dxcqdemand = 0.0
js = 1
do i = 1, nid
je = xchOff(i)
if (je-js.gt.0) write(*,*) 'Warning: cell received > 1 qdemand'
do j = js, je
k = xchIdx(j)
if (k.le.0) then
write(*,*) 'Error: coupling node index out of range'
stop 1
end if
q = qdemand(k)
if (q.ne.mv) then
! the values got are volumes, recalculate them to fluxes
q = q !/delt !we for now assume that the values got are already fluxes!
else
q = 0.0
end if
dxcqdemand(i) = dxcqdemand(i) + q
end do
js = je + 1
end do
! save pointers
call sgwf2dxc1psv(igrid)
mf2005_GetQdemand = .true.
end function
logical function mf2005_GetUnsaturatedZoneFlux(igrid, !altijd 1
1 nid, !number of ID's over which exchange takes place
1 unsflux, !unsaturated zone flux
1 xchIdx, !XchSim2ModIdx Array index for mapping ID1-->ID2, in dit geval dus mapping van de Simgro nodes betrokken bij de Modflow-Simgro koppeling, en de Modflow nodes betrokken bij deze koppeling
1 xchOff, !XchSim2ModOff
1 mv) !mv
!... modules
use gwfbasmodule, only: delt
use gwfdxcmodule, only: dxcuzflux
implicit none
! arguments
integer, intent(in) :: igrid
integer, intent(in) :: nid
real, dimension(*), intent(inout) :: unsflux
integer, dimension(*), intent(in) :: xchIdx
integer, dimension(nid), intent(in) :: xchOff
real, intent(in) :: mv
!... locals
integer :: i, j, js, je, k, ilay, irow, icol
real :: q
!.......................................................................
! get pointers
call sgwf2bas7pnt(igrid)
call sgwf2dxc1pnt(igrid)
dxcuzflux = 0.0
js = 1
do i = 1, nid
je = xchOff(i)
if (je-js.gt.0) write(*,*) 'Warning: cell received > 1 uszflux'
do j = js, je
k = xchIdx(j)
if (k.le.0) then
write(*,*) 'Error: coupling node index out of range'
stop 1
end if
q = unsflux(k)
if (q.ne.mv) then
! the values got are volumes, recalculate them to fluxes
q = q/delt
else
q = 0.0
end if
dxcuzflux(i) = dxcuzflux(i) + q
end do
js = je + 1
end do
! save pointers
call sgwf2dxc1psv(igrid)
mf2005_GetUnsaturatedZoneFlux = .true.
end function
!> Set storage factor.
logical function mf2005_GetStorageFactorLPF(igrid,strfct,
1 nid,xchIdx,xchOff,mv)
!... modules
use gwflpfmodule, only: sc1
use gwfdxcmodule, only: dxcic, dxcir, dxcil
implicit none
!... arguments
integer, intent(in) :: igrid
integer, intent(in) :: nid
real, dimension(*), intent(inout) :: strfct
integer, dimension(*), intent(in) :: xchIdx
integer, dimension(nid), intent(in) :: xchOff
real, intent(in) :: mv
!... locals
logical :: ok
integer :: i, j, js, je, k, ilay, irow, icol
real :: s
!.......................................................................
!... get pointers
call sgwf2lpf7pnt(igrid)
call sgwf2dxc1pnt(igrid)
ok = .true.
js = 1
do i = 1, nid
ilay = dxcil(i)
irow = dxcir(i)
icol = dxcic(i)
je = xchOff(i)
if (je-js.gt.0) write(*,*) 'Warning: cell received > 1 sf1'
s = mv
do j = js, je
k = xchIdx(j)
if (k.le.0) then
ok = .false.
mf2005_GetStorageFactorLPF = ok
return
end if
if (strfct(k).ne.mv) then
if (s.eq.mv) s = 0.0
s = s + strfct(k)
end if
end do
if (s.ne.mv) then
! set storage factor
sc1(icol,irow,ilay) = s
endif
js = je + 1
end do
!... pointer save
call gwf2lpf7psv(igrid)
mf2005_GetStorageFactorLPF = ok
end function
!> Set storage factor.
logical function mf2005_GetStorageFactor(igrid,strfct,
1 nid,xchIdx,xchOff,mv)
!... modules
use gwfbcfmodule, only: sc1
use gwfdxcmodule, only: dxcic, dxcir, dxcil
implicit none
!... arguments
integer, intent(in) :: igrid
integer, intent(in) :: nid
real, dimension(*), intent(inout) :: strfct
integer, dimension(*), intent(in) :: xchIdx
integer, dimension(nid), intent(in) :: xchOff
real, intent(in) :: mv
!... locals
logical :: ok
integer :: i, j, js, je, k, ilay, irow, icol
real :: s
!.......................................................................
!... get pointers
call sgwf2bcf7pnt(igrid)
call sgwf2dxc1pnt(igrid)
ok = .true.
js = 1
do i = 1, nid
ilay = dxcil(i)
irow = dxcir(i)
icol = dxcic(i)
je = xchOff(i)
if (je-js.gt.0) write(*,*) 'Warning: cell received > 1 sf1'
s = mv
do j = js, je
k = xchIdx(j)
if (k.le.0) then
ok = .false.
mf2005_GetStorageFactor = ok
return
end if
if (strfct(k).ne.mv) then
if (s.eq.mv) s = 0.0
s = s + strfct(k)
end if
end do
if (s.ne.mv) then
! set storage factor
sc1(icol,irow,ilay) = s
endif
js = je + 1
end do
!... pointer save
call sgwf2bcf7psv(igrid)
mf2005_GetStorageFactor = ok
end function
logical function mf2005_PutQrealized(igrid,xchQrealized,nid,
1 xchIdx,xchOff,mv)
USE GWFMNW1MODULE, ONLY:WELL2
implicit none
!... arguments
integer, intent(in) :: igrid
integer, intent(in) :: nid
real, dimension(nid), intent(out) :: xchQrealized
real, intent(in) :: mv
integer, dimension(*), intent(in) :: xchIdx
integer, dimension(nid), intent(in) :: xchOff
!... locals
logical :: ok
integer :: i, j, k, js, je
real :: q
!.......................................................................
!... get pointers
xchQrealized = 0.0
js = 1
do i = 1, nid
je = xchOff(i)
if (je-js.gt.0) write(*,*) 'Warning: cell received > 1 qdemand'
do j = js, je
k = xchIdx(j)
if (k.le.0) then
write(*,*) 'Error: coupling node index out of range'
stop 1
end if
q = WELL2(3,k)
if (q.eq.mv) q = 0.0
xchQrealized(i) = xchQrealized(i) + q
end do
js = je + 1
end do
! save pointers
call sgwf2dxc1psv(igrid)
ok = .true.
mf2005_PutQrealized = ok
end function
logical function mf2005_PutSeepageFlux(igrid,xchSeepage,
1 xchCells,nxch,mv,mflag)
use global, only: delr, delc
use gwfbcfmodule, only: seepage, seepagemv
implicit none
!... arguments
integer, intent(in) :: igrid
integer, intent(in) :: nxch
integer, dimension(3,nxch), intent(in) :: xchCells
real, dimension(nxch), intent(out) :: xchSeepage
real, intent(in) :: mv
logical, intent(in) :: mflag
!... locals
logical :: ok
integer :: i, irow, icol, ilay
real :: s, area
!.......................................................................
!... get pointers
call sgwf2bas7pnt(igrid)
call sgwf2bcf7pnt(igrid)
do i = 1, nxch
ilay = xchCells(1,i)
irow = xchCells(2,i)
icol = xchCells(3,i)
! only add for the first layer
if (ilay.eq.1) then
s = seepage(icol,irow)
if (s.eq.seepagemv) then
s = mv
else
area = delr(icol)*delc(irow)
if (.not.mflag) area = 1.0
s = s/area ! m3 --> m if mflag = .true.
end if
else
s = mv
end if
xchSeepage(i) = s
end do
ok = .true.
mf2005_PutSeepageFlux = ok
end function
logical function mf2005_PutSeepageSalt(igrid,xchSalt,
1 xchCells,nxch,mv,mflag)
use gwfbcfmodule, only: seepage, seepagemv
use gwfdxcmodule, only: seepageconc
implicit none
!... arguments
integer, intent(in) :: igrid
integer, intent(in) :: nxch
integer, dimension(3,nxch), intent(in) :: xchCells
real, dimension(nxch), intent(out) :: xchSalt
real, intent(in) :: mv
logical, intent(in) :: mflag
!... locals
logical :: ok
integer :: i, irow, icol, ilay
real :: seep, conc, flux, area
!.......................................................................
!... get pointers
call sgwf2bas7pnt(igrid)
call sgwf2bcf7pnt(igrid)
call sgwf2dxc1pnt(igrid)
do i = 1, nxch
ilay = xchCells(1,i)
irow = xchCells(2,i)
icol = xchCells(3,i)
! only add for the first layer
if (ilay.eq.1) then
seep = seepage(icol,irow)
conc = seepageconc(icol,irow)
flux = mv
if (seep.ne.seepagemv .and. conc.gt.0.) then
if (seep.lt.0.) flux = -seep*conc
end if
else
flux = mv
end if
xchSalt(i) = flux
end do
ok = .true.
mf2005_PutSeepageSalt = ok
end function
logical function mf2005_PutRiverFlux(igrid,xchRivFlux,
1 xchCells,nxch,mv,
1 nhrivsys,hrivsys,nwrivsys,wrivsys,
1 mflag,wells)
use global, only: buff, delr, delc
use gwfrivmodule, only: rivr, nriver, nrivvl,
1 irivsubsys, irivrconc
implicit none
!... arguments
integer, intent(in) :: igrid
integer, intent(in) :: nxch
integer, dimension(3,nxch), intent(in) :: xchCells
real, dimension(nxch), intent(out) :: xchRivFlux
real, intent(in) :: mv
integer, intent(in) :: nhrivsys
integer, dimension(nhrivsys), intent(in) :: hrivsys
integer, intent(in) :: nwrivsys
integer, dimension(nwrivsys), intent(in) :: wrivsys
logical, intent(in) :: mflag
logical, intent(in) :: wells
!... locals
logical :: ok, add
integer :: i, j, n, irow, icol, ilay, isys
real :: flux, conc, area
!.......................................................................
!... get pointers
call sgwf2bas7pnt(igrid)
call sgwf2riv7pnt(igrid)
!... get number of rivers
if (associated(nriver)) then
n = nriver
else
n = 0
end if
!... use the working buffer for temporary storage and initialize
buff = mv
do i = 1, n
add = .true.
ilay = rivr(1,i)
irow = rivr(2,i)
icol = rivr(3,i)
flux = rivr(nrivvl,i)
conc = rivr(irivrconc,i)
isys = rivr(irivsubsys,i)
! skip subsystem H
do j = 1, nhrivsys
if (isys.eq.hrivsys(j)) add = .false.
end do
if (.not.wells) then
do j = 1, nwrivsys
if (isys.eq.wrivsys(j)) add = .false.
end do
else
do j = 1, nwrivsys
if (isys.ne.wrivsys(j)) add = .false.
end do
if (add .and. conc.lt.0.0) add = .false.
end if
if (add) then
if (buff(icol,irow,1).eq.mv) buff(icol,irow,1) = 0.0
buff(icol,irow,1) = buff(icol,irow,1) + flux
end if
end do
!... Copy to exchange array
do i = 1, nxch
ilay = xchCells(1,i)
irow = xchCells(2,i)
icol = xchCells(3,i)
flux = buff(icol,irow,1)
if (flux.ne.mv) then
area = delr(icol)*delc(irow)
if (.not.mflag) area = 1.0
flux = flux/area ! m3 --> m if mflag = .true.
end if
xchRivFlux(i) = flux
end do
ok = .true.
mf2005_PutRiverFlux = ok
end function
logical function mf2005_PutSaltFlux(igrid,xchRivFlux,
1 xchCells,nxch,mv,nwrivsys,wrivsys)
use global, only: buff, delr, delc
use gwfrivmodule, only: rivr, nriver, nrivvl,
1 irivsubsys, irivrconc
implicit none
!... arguments
integer, intent(in) :: igrid
integer, intent(in) :: nxch
integer, dimension(3,nxch), intent(in) :: xchCells
real, dimension(nxch), intent(out) :: xchRivFlux
real, intent(in) :: mv
integer, intent(in) :: nwrivsys
integer, dimension(nwrivsys), intent(in) :: wrivsys
!... locals
logical :: ok, add
integer :: i, j, n, irow, icol, ilay
real :: flux, conc, saltflux, area
!.......................................................................
!... get pointers
call sgwf2bas7pnt(igrid)
call sgwf2riv7pnt(igrid)
!... get number of rivers
if (associated(nriver)) then
n = nriver
else
n = 0
end if
!... use the working buffer for temporary storage and initialize
buff = mv
do i = 1, n
add = .false.
if (irivsubsys.gt.0) then
do j = 1, nwrivsys
if (rivr(irivsubsys,i).eq.wrivsys(j)) add = .true.
end do
end if
ilay = rivr(1,i)
irow = rivr(2,i)
icol = rivr(3,i)
flux = rivr(nrivvl,i)
conc = rivr(irivrconc,i)
saltflux = mv
if (conc.gt.0.0) then ! work-around, to be changed for proper missing value
if (flux.lt.0.0) then
saltflux = flux*conc
else
saltflux = 0.0
end if
end if
if (saltflux.eq.mv) add = .false.
if (add) then
if (buff(icol,irow,1).eq.mv) buff(icol,irow,1) = 0.0
buff(icol,irow,1) = buff(icol,irow,1) + saltflux
end if
end do
!... Copy to exchange array
do i = 1, nxch
ilay = xchCells(1,i)
irow = xchCells(2,i)
icol = xchCells(3,i)
flux = buff(icol,irow,1)
xchRivFlux(i) = flux
end do
ok = .true.
mf2005_PutSaltFlux = ok
end function
logical function mf2005_PutSaltFluxSeepage(igrid,xchFlux,
1 xchCells,nxch,mv)
use gwfbcfmodule, only: seepage, seepagemv
use gwfdxcmodule, only: seepageconc
implicit none
!... arguments
integer, intent(in) :: igrid
integer, intent(in) :: nxch
integer, dimension(3,nxch), intent(in) :: xchCells
real, dimension(nxch), intent(out) :: xchFlux
real, intent(in) :: mv
!... locals
logical :: ok, add
integer :: i, j, n, irow, icol, ilay
real :: flux, seep, conc
!.......................................................................
!... get pointers
call sgwf2bcf7pnt(igrid)
call sgwf2dxc1pnt(igrid)
!... determine seepage flux
do i = 1, nxch
ilay = xchCells(1,i)
irow = xchCells(2,i)
icol = xchCells(3,i)
flux = mv
seep = seepage(icol,irow)
conc = seepageconc(icol,irow)
if (seep.ne.seepagemv .and. conc > 0.) then
flux = 0.
if (seep < 0.) then
flux = -seep*conc ! [m3]*[mg/l] = [m3]*[g/m3] = [g]
end if
end if
xchFlux(i) = flux
end do
ok = .true.
mf2005_PutSaltFluxSeepage = ok
end function
logical function mf2005_PutDrainFlux(igrid,xchDrnFlux,
1 xchCells,nxch,mv,mflag)
use global, only: buff, delr, delc
use gwfdrnmodule, only: drai, ndrain, ndrnvl, idrnsubsys
implicit none
!... arguments
integer, intent(in) :: igrid
integer, intent(in) :: nxch
integer, dimension(3,nxch), intent(in) :: xchCells
real, dimension(nxch), intent(out) :: xchDrnFlux
real, intent(in) :: mv
logical, intent(in) :: mflag
!... locals
logical :: ok, add
integer :: i, n, irow, icol, ilay
real :: flux, area
!.......................................................................
!... get pointers
call sgwf2bas7pnt(igrid)
call sgwf2drn7pnt(igrid)
!... get number of rivers
if (associated(ndrain)) then
n = ndrain
else
n = 0
end if
!... use the working buffer for temporary storage and initialize
buff = mv
do i = 1, n
add = .true.
ilay = drai(1,i)
irow = drai(2,i)
icol = drai(3,i)
flux = drai(ndrnvl,i)
if (add) then
if (buff(icol,irow,1).eq.mv) buff(icol,irow,1) = 0.0
buff(icol,irow,1) = buff(icol,irow,1) + flux
end if
end do
!... Copy to exchange array
do i = 1, nxch
ilay = xchCells(1,i)
irow = xchCells(2,i)
icol = xchCells(3,i)
flux = buff(icol,irow,1)
if (flux.ne.mv) then
area = delr(icol)*delc(irow)
if (.not.mflag) area = 1.0
flux = flux/area ! m3 --> m if mflag = .true.
end if
xchDrnFlux(i) = flux
end do
ok = .true.
mf2005_PutDrainFlux = ok
end function
!> Put the river subsystems to skip.
logical function mf2005_PutModMozRiversToSkip(igrid,nhriv,
1 hriv)
!... modules
use gwfdxcmodule, only: maxnhrivsys, nhrivsys, hrivsys
implicit none
!... arguments
integer, intent(in) :: igrid
integer, intent(in) :: nhriv
integer, dimension(nhriv), intent(in) :: hriv
!... locals
logical :: ok
!.......................................................................
!... get pointers
call sgwf2dxc1pnt(igrid)
ok = .true.
if (nhriv.gt.maxnhrivsys) then
ok = .false.
mf2005_PutModMozRiversToSkip = ok
return
end if
nhrivsys = nhriv
hrivsys(1:nhrivsys) = hriv(1:nhrivsys)
!... save pointers
call sgwf2dxc1psv(igrid)
!... return
mf2005_PutModMozRiversToSkip = ok
end function
!> Return number of exchange items (LSW IDs).
logical function mf2005_PutModMozNumberOfIDs(igrid, nxch)
!... modules
use gwfdxcmodule, only: ndxclsw
implicit none
!... arguments
integer, intent(in) :: igrid
integer, intent(out) :: nxch
!... locals
logical :: ok
!.......................................................................
!... get pointers
call sgwf2dxc1pnt(igrid)
!... check
ok = .true.
if (.not.associated(ndxclsw)) then
ok = .false.
mf2005_PutModMozNumberOfIDs = ok
return
end if
nxch = ndxclsw
if (nxch.le.0) ok = .false.
mf2005_PutModMozNumberOfIDs = ok
end function
!> Return number of exchange items (PV IDs).
logical function mf2005_PutModMozPVNumberOfIDs(igrid, nxch)
!... modules
use gwfdxcmodule, only: ndxcpv
implicit none
!... arguments
integer, intent(in) :: igrid
integer, intent(out) :: nxch
!... locals
logical :: ok
!.......................................................................
!... get pointers
call sgwf2dxc1pnt(igrid)
!... check
ok = .true.
if (.not.associated(ndxcpv)) then
ok = .false.
mf2005_PutModMozPVNumberOfIDs = ok
return
end if
nxch = ndxcpv
if (nxch.le.0) ok = .false.
mf2005_PutModMozPVNumberOfIDs = ok
end function
!> Return MODFLOW exchange IDs.
logical function mf2005_PutModMozIDs(igrid,ids)
!... modules
use gwfdxcmodule, only: dxcidlsw, ndxclsw
implicit none
!... arguments
integer, intent(in) :: igrid
integer, dimension(*), intent(out) :: ids
!... locals
logical :: ok
integer :: i
!.......................................................................
!... set pointers
call sgwf2dxc1pnt(igrid)
!... check
ok = .true.
if (.not.associated(dxcidlsw)) then
ok = .false.
mf2005_PutModMozIDs = ok
return
end if
!... Copy the IDs
do i = 1, ndxclsw
ids(i) = dxcidlsw(i)
end do
mf2005_PutModMozIDs = ok
end function
!> Return MODFLOW exchange IDs.
logical function mf2005_PutModMozPVIDs(igrid,ids)
!... modules
use gwfdxcmodule, only: dxcidpv, ndxcpv
implicit none
!... arguments
integer, intent(in) :: igrid
integer, dimension(*), intent(out) :: ids
!... locals
logical :: ok
integer :: i
!.......................................................................
!... set pointers
call sgwf2dxc1pnt(igrid)
!... check
ok = .true.
if (.not.associated(dxcidpv)) then
ok = .false.
mf2005_PutModMozPVIDs = ok
return
end if
!... Copy the IDs
do i = 1, ndxcpv
ids(i) = dxcidpv(i)
end do
mf2005_PutModMozPVIDs = ok
end function
logical function mf2005_GetLSWLevels(igrid,
1 levels,nid,xchIdx,xchOff,mv)
!... modules
use gwfdxcmodule, only: dxclevlsw, dxcmv
implicit none
!... arguments
integer, intent(in) :: igrid
integer, intent(in) :: nid
real, dimension(*), intent(inout) :: levels
integer, dimension(*), intent(in) :: xchIdx
integer, dimension(nid), intent(in) :: xchOff
real, intent(in) :: mv
!... locals
integer :: i, j, js, je, k, ilay, irow, icol
real :: lev
!.......................................................................
! get pointers
call sgwf2dxc1pnt(igrid)
dxclevlsw = dxcmv
js = 1
do i = 1, nid
je = xchOff(i)
if (je-js.gt.0) write(*,*) 'Warning: cell received > 1 uszflux'
do j = js, je
k = xchIdx(j)
if (k.le.0) then
write(*,*) 'Error: coupling node index out of range'
stop 1
end if
lev = levels(k)
if (lev.eq.mv) lev = dxcmv
dxclevlsw(i) = lev
end do
js = je + 1
end do
! save pointers
call sgwf2dxc1psv(igrid)
mf2005_GetLSWLevels = .true.
end function
logical function mf2005_GetPVLevels(igrid,
1 levels,nid,xchIdx,xchOff,mv)
!... modules
use gwfdxcmodule, only: dxclevpv, dxcmv
implicit none
!... arguments
integer, intent(in) :: igrid
integer, intent(in) :: nid
real, dimension(*), intent(inout) :: levels
integer, dimension(*), intent(in) :: xchIdx
integer, dimension(nid), intent(in) :: xchOff
real, intent(in) :: mv
!... locals
integer :: i, j, js, je, k, ilay, irow, icol
real :: lev
!.......................................................................
! set pointers
call sgwf2dxc1pnt(igrid)
dxclevpv = dxcmv
js = 1
do i = 1, nid
je = xchOff(i)
if (je-js.gt.0) then
write(*,*) 'Warning: cell received > 1 levels'
end if
do j = js, je
k = xchIdx(j)
if (k.le.0) then
write(*,*) 'Error: coupling node index out of range'
stop 1
end if
lev = levels(k)
if (lev.eq.mv) lev = dxcmv
dxclevpv(i) = lev
end do
js = je + 1
end do
! save pointers
call sgwf2dxc1psv(igrid)
mf2005_GetPVLevels = .true.
end function
logical function mf2005_TimeserieInit(igrid)
!... modules
use imod_utl, only: imod_utl_pol1locater
use global, only: iunit, nlay, nrow, ncol
use gwfmetmodule, only: coord_xll_nb,coord_yll_nb,coord_xur_nb,
1 coord_yur_nb,cdelr,cdelc,resultdir
use m_mf2005_iu
use tsvar
implicit none
!... arguments
integer, intent(in) :: igrid
!... locals
logical :: ok, valid
integer :: jj, i, ilay, irow, icol
real :: x, y
!.......................................................................
ok = .true.
if (iipf.eq.0) then
mf2005_TimeserieInit = ok
return
end if
! set pointers
call sgwf2bas7pnt(igrid)
call sgwf2met1pnt(igrid)
if (IUNIT(IUMET).le.0) then
ok = .false.
mf2005_TimeserieInit = ok
return
end if
if (.not.associated(coord_xll_nb).or.
1 .not.associated(coord_yll_nb).or.
1 .not.associated(coord_yur_nb).or.
1 .not.associated(coord_xur_nb).or.
1 .not.associated(cdelr).or.
1 .not.associated(cdelc)) then
ok = .false.
mf2005_TimeserieInit = ok
return
end if
do jj = 1, abs(iipf)
do i = 1, ts(jj)%nrowipf
x = ts(jj)%stvalue(i)%x
y = ts(jj)%stvalue(i)%y
ilay = ts(jj)%stvalue(i)%ilay
valid = .true.
if (x.lt.coord_xll_nb .or. x.gt.coord_xur_nb) valid = .false.
if (y.lt.coord_yll_nb .or. y.gt.coord_yur_nb) valid = .false.
if (ilay.lt.0 .or. ilay.gt.nlay) valid = .false.
ts(jj)%stvalue(i)%valid = valid
if (valid) then ! store indices
icol = ts(jj)%stvalue(i)%icol
irow = ts(jj)%stvalue(i)%irow
if (icol.eq.0 .or. irow.eq.0) then
call imod_utl_pol1locater(cdelr,ncol+1,x,icol)
call imod_utl_pol1locater(cdelc,nrow+1,y,irow)
ts(jj)%stvalue(i)%icol = icol
ts(jj)%stvalue(i)%irow = irow
end if
end if
end do
end do
mf2005_TimeserieInit = ok
end function
logical function mf2005_TimeserieGetHead(igrid)
!... modules
use global, only: hnew, iunit, nlay, nrow, ncol
use tsvar
implicit none
!... arguments
integer, intent(in) :: igrid
!... functions
real :: mf2005_tserie1hmean
!... locals
logical :: ok
integer :: jj, i, ilay, irow, icol
real :: x, y, h
!.......................................................................
ok = .true.
! set pointers
call sgwf2bas7pnt(igrid)
if (iipf.eq.0) then
mf2005_TimeserieGetHead = ok
return
end if
do jj = 1, abs(iipf)
do i = 1, ts(jj)%nrowipf
if (.not.ts(jj)%stvalue(i)%valid) cycle ! skip invalid data
icol = ts(jj)%stvalue(i)%icol
irow = ts(jj)%stvalue(i)%irow
if (icol.eq.0 .or. irow.eq.0) then
ok = .false.
mf2005_TimeserieGetHead = ok
return
end if
ilay = ts(jj)%stvalue(i)%ilay
if(iipf.gt.0)then
h=real(hnew(icol,irow,ilay))
else
x = ts(jj)%stvalue(i)%x
y = ts(jj)%stvalue(i)%y
!## interpolate heads
h=mf2005_tserie1hmean(x,y,icol,irow,ilay)
endif
ts(jj)%stvalue(i)%c = h ! set computed value
end do
end do
mf2005_TimeserieGetHead = ok
end function
!> Enable PEST for MODFLOW.
logical function mf2005_GetPestFlag(flag)
!... modules
use global, only: lipest
implicit none
!... arguments
logical, intent(in) :: flag
!.......................................................................
lipest = flag
mf2005_GetPestFlag = .true.
end function
!> Set the MNQ target Q
logical function mf2005_SetMultiNodeWellTargetQ(n,rcl,q)
!... modules
use gwfmnw2module
implicit none
!... arguments
integer, intent(in) :: n
integer, dimension(3,n) :: rcl
real, dimension(n) :: q
!... locals
integer :: i
!.......................................................................
!... check if package is active
mf2005_SetMultiNodeWellTargetQ = .true.
do i = 1, n
end do
end function