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 KJH 20030327 -- Patched Hyd.K term in LPF option -- cel2wel function
C KJH 20030717 -- Patched budget output switch -- subroutine GWF1MNW1bd
c Cleaned output so outrageous pointers are not printed
c GZH 20050405 -- Converted calculations to use double precision
c KJH 20050419 -- Array WELL2 dimensioned to 18 to store well id
C AWH 20080411 -- Retrieve HDRY from GWFBASMODULE rather than from
C LPF, BCF, or HUF
c
MODULE GWFMNW1MODULE
DOUBLE PRECISION, PARAMETER :: TWOPI=2.0D0*3.1415926535897932D0
DOUBLE PRECISION, PARAMETER :: ZERO25=1.0D-25, ZERO20=1.0D-20
DOUBLE PRECISION, PARAMETER :: ZERO8=1.0D-8, BIG=1.0D30
CHARACTER(LEN=200),SAVE,POINTER:: MNWNAME
INTEGER, SAVE,POINTER :: NWELL2, MXWEL2, IWL2CB, KSPREF
INTEGER, SAVE,POINTER :: IWELPT, NOMOITER
DOUBLE PRECISION, SAVE,POINTER :: PLOSS
DOUBLE PRECISION, SAVE,POINTER :: SMALL, HMAX
CHARACTER(LEN=32),SAVE,DIMENSION(:), POINTER :: MNWSITE
INTEGER, SAVE,DIMENSION(:), POINTER :: IOWELL2
DOUBLE PRECISION, SAVE,DIMENSION(:,:), POINTER :: WELL2
DOUBLE PRECISION, SAVE,DIMENSION(:,:,:),POINTER :: HREF
real, save, dimension(:), pointer :: demandbuff => null() ! DLT
TYPE GWFMNWTYPE
CHARACTER(LEN=200), POINTER :: MNWNAME
INTEGER, POINTER :: NWELL2, MXWEL2, IWL2CB, KSPREF
INTEGER, POINTER :: IWELPT, NOMOITER
DOUBLE PRECISION, POINTER :: PLOSS
DOUBLE PRECISION, POINTER :: SMALL, HMAX
CHARACTER(LEN=32), DIMENSION(:), POINTER :: MNWSITE
INTEGER, DIMENSION(:), POINTER :: IOWELL2
DOUBLE PRECISION, DIMENSION(:,:), POINTER :: WELL2
DOUBLE PRECISION, DIMENSION(:,:,:),POINTER :: HREF
real, dimension(:), pointer :: demandbuff => null() ! DLT
END TYPE
TYPE(GWFMNWTYPE), SAVE:: GWFMNWDAT(10)
END MODULE GWFMNW1MODULE
C
c-------------------------------------------------------------------------
c
SUBROUTINE GWF2MNW17AR(In, Iusip, Iude4, Iusor, Iupcg, Iulmg,
+ Iugmg, Fname, Igrid)
C VERSION 20020819 KJH
c
c----- MNW by K.J. Halford 1/31/98
c ******************************************************************
c allocate array storage for well package
c ******************************************************************
c
c specifications:
c ------------------------------------------------------------------
USE GLOBAL, ONLY: IOUT,NCOL,NROW,NLAY
USE GWFMNW1MODULE
USE SIPMODULE,ONLY:HCLOSE
USE DE4MODULE,ONLY:HCLOSEDE4
USE PCGMODULE,ONLY:HCLOSEPCG
USE GMGMODULE,ONLY:HCLOSEGMG
IMPLICIT NONE
c ------------------------------------------------------------------
INTRINSIC ABS
INTEGER, EXTERNAL :: IFRL
EXTERNAL NCREAD, UPCASE, QREAD, USTOP
c ------------------------------------------------------------------
c Arguments
c ------------------------------------------------------------------
INTEGER :: In, Iusip, Iude4, Iusor, Iupcg, Iulmg, Iugmg, Igrid
CHARACTER(LEN=200) :: Fname !!08/19/02KJH-MODIFIED
c ------------------------------------------------------------------
c Local Variables
c ------------------------------------------------------------------
REAL :: bs
INTEGER :: ierr, io, iok, jf, ke, kf, ki, kio
DOUBLE PRECISION :: rn(25)
CHARACTER(LEN=256) :: txt, tx2
c ------------------------------------------------------------------
c Static Variables
c ------------------------------------------------------------------
CHARACTER(LEN=6) :: ftag(3)
INTEGER :: icf(3)
DATA ftag/'WEL1 ', 'BYNODE', 'QSUM '/
DATA icf/4, 6, 4/
c ------------------------------------------------------------------
ALLOCATE (MNWNAME, NWELL2, MXWEL2, IWL2CB, NOMOITER, KSPREF,
+ IWELPT)
ALLOCATE (PLOSS, SMALL, HMAX, IOWELL2(3),
+ HREF(NCOL,NROW,NLAY))
c
IOWELL2(1) = 0
IOWELL2(2) = 0
IOWELL2(3) = 0
c
c1------identify package and initialize nwell2
WRITE (IOUT, 9001) In
9001 FORMAT (/, ' MNW1 -- MULTI-NODE WELL 1 PACKAGE, VERSION 7,',
+ ' 11/07/2005.', /, ' INPUT READ FROM UNIT', i4)
NWELL2 = 0
c
c2------read max number of wells and
c2------unit or flag for cell-by-cell flow terms.
CALL NCREAD(In, txt, ierr)
CALL UPCASE(txt)
c
ki = INDEX(txt, 'REF')
IF ( ki.GT.0 ) THEN
tx2 = txt(ki:256)
CALL QREAD(rn, 1, tx2, ierr)
IF ( ierr.EQ.0 ) KSPREF = IFRL(rn(1))
txt(ki:256) = ' '
ELSE
KSPREF = 1
ENDIF
c
CALL QREAD(rn, 4, txt, ierr)
MXWEL2 = IFRL(rn(1))
IWL2CB = 0
IF ( ierr.LE.2 ) IWL2CB = IFRL(rn(2))
IWELPT = 0
IF ( ierr.EQ.1 ) IWELPT = IFRL(rn(3))
NOMOITER = 9999
IF ( ierr.EQ.0 ) NOMOITER = IFRL(rn(4))
c
WRITE (IOUT, 9002) MXWEL2
IF ( IWL2CB.GT.0 ) WRITE (IOUT, 9003) IWL2CB
IF ( IWL2CB.LT.0 ) WRITE (IOUT, 9004)
WRITE (IOUT, 9005) KSPREF
WRITE (IOUT, 9006) NOMOITER
9002 FORMAT (' MAXIMUM OF', i7, ' WELLS')
9003 FORMAT (' CELL-BY-CELL FLOWS WILL BE RECORDED ON UNIT', i3)
9004 FORMAT (' CELL-BY-CELL FLOWS WILL BE PRINTED WHEN ICBCFL NOT 0')
9005 FORMAT (' The heads at the beginning of SP:', i4,
+ ' will be the default reference elevations.', /)
9006 FORMAT (' Flow rates will not be estimated after the', i4,
+ 'th iteration')
c
c Define well model to be used
c
CALL NCREAD(In, txt, ierr)
CALL UPCASE(txt)
PLOSS = 0.0D0 !! Default use of Skin so linear loss varies with T
IF ( INDEX(txt, 'LINEAR').GT.0 ) THEN
PLOSS = 1.0D0 !! ADD THIS LINE to make sure that the power term is 1 for the linear model
ki = INDEX(txt, ':') + 1
tx2 = txt(ki:256)
CALL QREAD(rn, 1, tx2, ierr)
IF ( ierr.EQ.0 ) PLOSS = rn(1)
c Add error checking to shut down MODFLOW
bs = 3.6 !! Maximum limit on power term
IF ( PLOSS.GT.bs ) THEN
WRITE (*, *) 'Power term of', PLOSS, ' exceeds maximum of', bs
WRITE (IOUT, *) 'Power term of', PLOSS, ' exceeds maximum of',
+ bs
C
C When compiling MNW with Modflow-96, comment out the call to
C USTOP and uncomment the STOP statement
CALL USTOP(' ')
C STOP
C
ENDIF
c
ENDIF
c
c Test for a specified PREFIX NAME for time series output from MNW7OT
c
CALL NCREAD(In, txt, ierr)
tx2 = txt
CALL UPCASE(tx2)
kf = INDEX(tx2, 'PREFIX:')
IF ( kf.GT.0 ) THEN
MNWNAME = txt(kf+7:256)
ke = INDEX(MNWNAME, ' ')
MNWNAME(ke:200) = ' '
tx2 = MNWNAME
CALL UPCASE(tx2)
IF ( INDEX(tx2, 'FILEPREFIX').GT.0 ) THEN
MNWNAME = Fname
ke = INDEX(MNWNAME, '.')
MNWNAME(ke:200) = ' '
ENDIF
ELSE
MNWNAME = 'OUTput_MNW'
BACKSPACE (In)
ENDIF
c
c Test for creation of a WEL1 package and auxillary output files
c
iok = 1
DO WHILE ( iok.EQ.1 )
CALL NCREAD(In, txt, ierr)
tx2 = txt
CALL UPCASE(tx2)
kf = INDEX(tx2, 'FILE:')
IF ( kf.GT.0 ) THEN
kio = 0
jf = 0
DO WHILE ( kio.EQ.0 .AND. jf.LT.3 )
jf = jf + 1
kio = INDEX(tx2, ftag(jf)(1:icf(jf)))
IF ( kio.GT.0 ) THEN
tx2 = txt(kio+1+icf(jf):256)
CALL QREAD(rn, 1, tx2, ierr)
IF ( ierr.EQ.0 ) THEN
IOWELL2(jf) = IFRL(rn(1))
c OC over ride is ALLTIME
IF ( INDEX(tx2, 'ALLTIME').GT.0 ) IOWELL2(jf)
+ = -IOWELL2(jf)
c Find and use file name
tx2 = txt(kf+5:256)
kf = INDEX(tx2, ' ') - 1
CLOSE (ABS(IOWELL2(jf)))
OPEN (ABS(IOWELL2(jf)), FILE=tx2(1:kf))
WRITE (tx2(253:256), '(i4)') ABS(IOWELL2(jf))
txt = ' A '//ftag(jf)
+ //' data input file will be written'//' to '//
+ tx2(1:kf)//' on unit '//tx2(253:256)
WRITE (IOUT, '(/1x,a79)') txt
IF ( jf.EQ.1 )
+ WRITE (ABS(IOWELL2(jf)),'(3i10)') MXWEL2, IWL2CB, IWELPT
ENDIF
ENDIF
ENDDO
ELSE
BACKSPACE (In)
iok = 0
ENDIF
ENDDO
c
c Write header in Auxillary BYNODE file if KPER=1 & IO>0
c
IF ( IOWELL2(2).NE.0 ) THEN
io = ABS(IOWELL2(2))
WRITE (io, 9008)
ENDIF
c
c Write header in Auxillary QSUM file if KPER=1 & IO>0
c
IF ( IOWELL2(3).NE.0 ) THEN
io = ABS(IOWELL2(3))
WRITE (io, 9009)
ENDIF
c
9008 FORMAT ('SiteID', 27x, 'Entry NODE', 5x, 'Total_Time', 8x, 'Q',
+ 5x, 'H-Well', 5x, 'H-Cell', 5x, 'QW-Avg')
9009 FORMAT ('SiteID', 31x, 'Entry', 5x, 'Total_Time', 10x, 'Qin',
+ 10x, 'Qout', 10x, 'Qsum', 5x, 'H-Well', 5x, 'QW-Avg')
c
C 4/18/2005 - KJH: Explicit well tracking addition changed 1st WELL2
C dimension from 17 to 18
ALLOCATE (WELL2(18, MXWEL2+1), MNWSITE(MXWEL2))
c
C-------SET SMALL DEPENDING ON CLOSURE CRITERIA OF THE SOLVER
IF ( Iusip.NE.0 ) SMALL = HCLOSE
IF ( Iude4.NE.0 ) SMALL = HCLOSEDE4
! IF ( Iusor.NE.0 ) SMALL = HCLOSESOR
IF ( Iupcg.NE.0 ) SMALL = HCLOSEPCG
IF ( Iulmg.NE.0 ) SMALL = 0.0D0 !LMG SETS HCLOSE TO ZERO
IF ( Iugmg.NE.0 ) SMALL = HCLOSEGMG
c
c-----SAVE POINTERS FOR GRID AND RETURN
CALL SGWF2MNW1PSV(Igrid)
c
c7------return
END SUBROUTINE GWF2MNW17AR
c
c_________________________________________________________________________________
c
SUBROUTINE GWF2MNW17RP(In, Iubcf, Iulpf, Iuhuf, Kper, Igrid)
c VERSION 20020819 KJH
C
c----- MNW by K.J. Halford 1/31/98
c ******************************************************************
c read new well locations, stress rates, conc, well char., and limits
c ******************************************************************
c
c specifications:
c ------------------------------------------------------------------
USE GLOBAL, ONLY:NODES,NCOL,NROW,NLAY,IBOUND,HOLD,HNEW,IOUT
USE GWFBASMODULE,ONLY:TOTIM,HDRY
USE GWFMNW1MODULE, ONLY:NWELL2,MXWEL2,IWELPT,PLOSS,HMAX,
1 MNWSITE,IOWELL2,WELL2,HREF,KSPREF,
2 BIG,ZERO25,
3 demandbuff ! DLT
use gwfdxcmodule, only: dxcqdemand
IMPLICIT NONE
INTRINSIC ABS, MAX, MOD, INT
INTEGER, EXTERNAL :: IFRL, IDIRECT
DOUBLE PRECISION, EXTERNAL :: CEL2WELBCF, CEL2WELLPF, CEL2WELHUF
EXTERNAL NCREAD, UPCASE, QREAD, USTOP
c ------------------------------------------------------------------
c Arguments
c ------------------------------------------------------------------
INTEGER, INTENT(IN) :: Iubcf, Iulpf, Iuhuf, Kper, Igrid
INTEGER, INTENT(INOUT) :: In
c ------------------------------------------------------------------
c Local Variables
c ------------------------------------------------------------------
DOUBLE PRECISION :: qfrcmn, qfrcmx, qreject, drytest, ipole, hlim
DOUBLE PRECISION :: hrfw, qsum, rw, cond, qact, sk, cf, q, rn(25)
INTEGER :: i, icmn, ierr, igrp, ii, iin, io, iok, ip, ipt, irmx
INTEGER :: itmp, j, k, kblk, kcp, kfini, ki, kpc, kqc, ksiteid
INTEGER :: ktab, m, mstep, n, n1, nb, ne, ngrp, nl, nn, node
INTEGER :: nstart, nqreject
INTEGER :: idwell,mm
CHARACTER(LEN=1) :: tab
CHARACTER(LEN=32) :: tempsite
CHARACTER(LEN=256) :: txt, tx2, txtraw
c ------------------------------------------------------------------
c-----SET POINTERS FOR THE CURRENT GRID.
CALL SGWF2MNW1PNT(Igrid)
cswm: SET POINTERS FOR FLOW PACKAGE TO GET K's FOR CEL2WEL
IF ( Iubcf.NE.0 ) CALL SGWF2BCF7PNT(Igrid)
IF ( Iulpf.NE.0 ) CALL SGWF2LPF7PNT(Igrid)
IF ( Iuhuf.NE.0 ) CALL SGWF2HUF7PNT(Igrid)
C
icmn = 1
kfini = 1
tab = CHAR(9)
qfrcmn = ZERO25
qfrcmx = ZERO25
qreject = 0.0D0
nqreject = 0
nl = 0
IF ( PLOSS.GT.1.001D0 ) nl = 1 !! Read NL loss Coefficient after Skin
c
c Check for setting the HREFerence array
CERB IN FIRST STRESS PERIOD, HOLD IS UNDEFINED, SO USE HNEW INSTEAD
IF ( Kper.EQ.1 ) THEN
HMAX = ABS(HNEW(1,1,1))
DO k = 1, NLAY
DO i = 1, NROW
DO j = 1, NCOL
HREF(j,i,k) = HNEW(j,i,k)
HMAX = MAX(ABS(HREF(j,i,k)),HMAX)
ENDDO
ENDDO
ENDDO
ELSE IF ( Kper.LE.KSPREF ) THEN
HMAX = ABS(HOLD(1,1,1))
DO k = 1, NLAY
DO i = 1, NROW
DO j = 1, NCOL
HREF(j,i,k) = HOLD(j,i,k)
HMAX = MAX(ABS(HREF(j,i,k)),HMAX)
ENDDO
ENDDO
ENDDO
ENDIF
c
c------------------------------------------------------------------
c The 18 rows of the well array store:
c Row # = Description
c------------------------------------------------------------------
c 1 = Well node locator (= cell number, counted from (1,1,1) in column direction)
c 2 = Desired flow rate
c 3 = Actual flow rate used
c 4 = Water Quality attribute to be averaged by flow
c 5 = Radius of wellbore
c 6 = Skin associated with well completion
c 7 = Minimum/Maximum head or drawdown
c 8 = Elevation of reference head for computing lift costs
c 9 = Water Quality Group identifier
c 10 = Water level in wellbore
c 11 = HCOF value / QWaverage
c 12 = RHS value
c 13 = Minimum flow rate - to turn off
c 14 = Minimum flow rate -- to turn on
c 15 = Reserve Desired flow rate
c 16 = Non-linear loss term
c 17 = Actual flow rate to individual nodes of a multi-node well
c kept for transport or other purposes !!7/13/2003 - CZ
c 18 = Explicit well identifier -- Same value for all nodes in a well
c------------------------------------------------------------------
c
c1------read itmp(number of wells or flag saying reuse well data)
CALL NCREAD(In, txtraw, ierr)
txt = txtraw
CALL UPCASE(txt)
CALL QREAD(rn, 1, txt, ierr)
itmp = rn(1)
c
IF ( itmp.LT.0 ) THEN
c if itmp less than zero reuse data. print message and return.
call sts2nodata(in) ! STS
WRITE (IOUT, 9001)
9001 FORMAT (1X,/1X,'REUSING MNW7 FROM LAST STRESS PERIOD')
RETURN
ELSE
c If itmp > 0, Test if wells are to replace old ones or be added.
c
call sts2data(in) ! STS
IF ( INDEX(txt, 'ADD').EQ.0 ) NWELL2 = 0
c
c return if there are no wells to read ........
IF ( itmp.EQ.0 ) RETURN
c
c Redundant well information is allowed in MNW
c
c Read additional well info
nstart = NWELL2
DO m = 1, itmp
CALL NCREAD(In, txtraw, ierr)
txt = txtraw
CALL UPCASE(txt)
c Attempt read with QREAD first
CALL QREAD(rn, 4, txt, ierr)
IF ( ierr.EQ.0 .AND. rn(5).LT.0.5D0 ) THEN
k = IFRL(rn(1))
j = IFRL(rn(2))
i = IFRL(rn(3))
q = rn(4)
irmx = IFRL(rn(6)) + 1
ELSE
c Use fixed form reader if errors were detected
READ (txt(1:40), '(3i10,f10.0)') k, j, i, q
irmx = 41
ENDIF
node = (k-1)*NCOL*NROW + (j-1)*NCOL + i
c Test for if well is in active grid ......
iok = 1
IF ( i.GT.NCOL .OR. j.GT.NROW .OR. node.GT.NODES ) iok = 0
drytest = HNEW(i,j,k) - HDRY
IF (iok.GT.0 .AND. ABS(drytest).GT.ZERO25) iok = IBOUND(i,j,k)
c
c Should MNW wells be allowed in specified-head cells?
IF ( iok.NE.0 ) THEN !! Allow SH now, "gt" for no SH
c Test for redundant info ......
ipt = 0
c The commented statements prevent having multiple MNW sites in the same cells
c nt = 0
c do while (nt.lt.nwell2 .and. ipt.eq.0 )
c nt = nt + 1
c if( well2(1,nt).eq.node ) ipt = nt
c enddo
IF ( ipt.EQ.0 ) THEN
NWELL2 = NWELL2 + 1
ipt = NWELL2
ENDIF
c
c Assign data now that the pointer is set
WELL2(1, ipt) = node
WELL2(2, ipt) = q
if(associated(demandbuff))then
WELL2(2, ipt) = demandbuff(ipt) !modflow-ribasim
elseif(associated(dxcqdemand))then
WELL2(2, ipt) = dxcqdemand(ipt) !modflow-ribasim
else
end if
ipole = 0.0D0
IF ( ABS(q).GT.ZERO25 ) ipole = q/ABS(q)
WELL2(3, ipt) = WELL2(2, ipt)
WELL2(13, ipt) = qfrcmn ! default lower limit
WELL2(14, ipt) = qfrcmx
c
c Look for limit modifications
kqc = INDEX(txt, 'QCUT')
kpc = INDEX(txt, '%CUT')
IF ( kqc+kpc.GT.0 .AND. ABS(q).GT.ZERO25 ) THEN
tx2 = txt(kqc+kpc+5:256)
CALL QREAD(rn, 2, tx2, ierr)
IF ( kqc.GT.0 ) THEN !! Absolute value was provided
rn(1) = 100.0D0*rn(1)/q !! Convert to percentage
rn(2) = 100.0D0*rn(2)/q
ENDIF
IF ( ierr.GE.1 ) rn(2) = rn(1)
WELL2(13, ipt) = rn(1)*0.01D0 !! convert percentages to fractions
WELL2(14, ipt) = rn(2)*0.01D0
IF ( INDEX(tx2, 'DEFAULT').GT.0 ) THEN
qfrcmn = rn(1)*0.01D0 !! New default lower limit
qfrcmx = rn(2)*0.01D0 !! New default upper limit
ENDIF
ENDIF
c
c Look for NonLinear coefficient
WELL2(16, ipt) = 0.0D0 !! NonLinear Loss Coefficient
kcp = INDEX(txt, 'CP:')
IF ( kcp.GT.0 .AND. nl.GT.0 ) THEN
tx2 = txt(kcp+3:256)
CALL QREAD(rn, 1, tx2, ierr)
IF ( ierr.EQ.0 ) THEN
WELL2(16, ipt) = rn(1)
c Could reset default C-term here to a non-zero value
ENDIF
ENDIF
c
c Look for Site Identifier -- Set to NO-PRINT if not present.
ksiteid = INDEX(txt, 'SITE')
IF ( ksiteid.GT.0 ) THEN
MNWSITE(ipt) = txtraw(ksiteid+5:256)
kblk = INDEX(MNWSITE(ipt), ' ')
ktab = INDEX(MNWSITE(ipt), tab)
IF ( kblk.GT.0 ) kfini = kblk
IF ( ktab.GT.0 .AND. ktab.LT.kblk ) kfini = ktab
IF ( kfini.LE.32 ) THEN
MNWSITE(ipt)(kfini:32) = ' '
ELSE
kfini = 32
ENDIF
txt(ksiteid:ksiteid+kfini+4) = ' '
ELSE
MNWSITE(ipt) = 'NO-PRINT '
ENDIF
c
c Read remaining info from card to set MNW specific parameters
tx2 = txt(irmx:256)
ki = INDEX(tx2, 'ZONE')
IF ( ki.GT.0 ) tx2(ki:256) = ' '
CALL QREAD(rn, 6, tx2, ierr)
c
c Move from well data from temp to permanent locations
DO ip = 1, 6 - ierr
WELL2(ip+3, ipt) = rn(ip)
ENDDO
IF ( ierr.GE.1 ) WELL2(9, ipt) = ipt
IF ( ierr.GE.2 .OR. ABS(WELL2(8,ipt)).GT.HMAX )
+ WELL2(8, ipt) = HREF(i,j,k)
c Compute HLIM relative to reference elevation if HLIM read was a DrawDown (DD)
IF ( INDEX(txt, 'DD').GT.0 )
+ WELL2(7, ipt) = ipole*WELL2(7, ipt) + WELL2(8, ipt)
IF ( ierr.GE.3 ) WELL2(7, ipt) = ipole*1.0D+26
IF ( ierr.GE.4 ) WELL2(6, ipt) = 0.0D0
IF ( ierr.GE.5 ) WELL2(5, ipt) = 0.0D0
IF ( ierr.GE.6 ) WELL2(4, ipt) = -1.0D0
c Flag as 2-point definition of a multi-node well if MULTI is detected.
IF ( INDEX(tx2, 'MULTI').GT.0 .AND.
+ ABS(WELL2(5,ipt)).GT.ZERO25 ) THEN
c Define direction and # of points in well
WELL2(2, ipt-1) = WELL2(2, ipt) + WELL2(2, ipt-1)
n1 = IFRL(WELL2(1, ipt-1))
mstep = IDIRECT(n1, node, NCOL, NROW)
DO nn = n1 + mstep, node, mstep
ipt = ipt + 1
NWELL2 = NWELL2 + 1
WELL2(1, ipt) = nn
WELL2(2, ipt) = 0.0D0
WELL2(3, ipt) = WELL2(2, ipt)
WELL2(4, ipt) = WELL2(4, ipt-1)
WELL2(5, ipt) = WELL2(5, ipt-1)
WELL2(6, ipt) = WELL2(6, ipt-1)
WELL2(16, ipt) = WELL2(16, ipt-1) !! NonLinear Loss Coefficient
WELL2(9, ipt) = WELL2(9, ipt-1)
WELL2(8, ipt) = -1.0D31
WELL2(13, ipt) = 0.0D0
WELL2(14, ipt) = 0.0D0
icmn = icmn + 1
WELL2(7, ipt) = icmn
ENDDO
c Flag as part of a multi-node well if MN is detected.
ELSE IF ( INDEX(tx2, 'MN').GT.0 .AND.
+ ABS(WELL2(5,ipt)).GT.ZERO25 ) THEN
c Set to very large -value to flag MN status
WELL2(8, ipt) = -1.0D31
icmn = icmn + 1
WELL2(7, ipt) = icmn
ELSE
icmn = 1
ENDIF
ELSE
c Sum details on rejected wells
qreject = qreject + q
nqreject = nqreject + 1
ENDIF ! IBOUND test statement
ENDDO ! end of well entry loop
c
c Process wells that are screened across multiple nodes
c
c Check for extreme contrast in conductance
c
WELL2(8, NWELL2+1) = 0.0D0
IF ( nstart.LT.1 ) nstart = 1
IF ( nstart.GT.NWELL2 ) nstart = NWELL2 - itmp + 1
DO i = nstart, NWELL2
IF ( WELL2(8, i).LT.-1.E30 .AND. WELL2(8, i+1).GT.-1.E30 .OR.
+ WELL2(8, i).LT.-1.E30 .AND. i.EQ.NWELL2 ) THEN
ngrp = IFRL(WELL2(7, i))
ne = i
nb = ne - ngrp + 1
hlim = WELL2(7, nb)
hrfw = WELL2(8, nb)
qsum = 0.0D0
tempsite = 'NO-PRINT '
DO iin = nb, ne
qsum = qsum + WELL2(2, iin)
IF ( MNWSITE(iin)(1:8).NE.'NO-PRINT' )
+ tempsite = MNWSITE(iin)
WELL2(2, iin) = 0.0D0
WELL2(7, iin) = 1.0D31
WELL2(8, iin) = 1.0D31
c Set to very large +value to flag MN status
ENDDO
c Set All SiteIDs in a multinode well to a common tag
DO iin = nb, ne
MNWSITE(iin) = tempsite
ENDDO
WELL2(7, nb) = ne
WELL2(2, ne) = qsum
WELL2(7, ne) = hlim
WELL2(8, ne) = hrfw
ENDIF
ENDDO ! end of multi-well pointer setting
c
ENDIF
c
c nwell2>mxwel2. print message. stop.
IF ( NWELL2.GT.MXWEL2 ) THEN
WRITE (IOUT, 9002) NWELL2, MXWEL2
9002 FORMAT (1X,/
1 1X,'nwell2(', i4, ') IS GREATER THAN mxwel2(', i4, ')')
C
C When compiling MNW with Modflow-96, comment out the call to
C USTOP and uncomment the STOP statement
CALL USTOP(' ')
C STOP
C
ENDIF
c
c Place desired flow rates in a reserved location
c
DO m = 1, NWELL2
WELL2(15, m) = WELL2(2, m)
ENDDO
c
c--assign unique well id for use with MT3DMS link package (cdl: 4/19/05)
m=0
IDwell=1
do while (m.lt.nwell2)
m=m+1
if(well2(8,m).gt.1.D30) then
do mm=m,ifrl(well2(7,m))
well2(18,mm)=IDwell
enddo
m=ifrl(well2(7,m))
else
well2(18,m)=IDwell
endif
IDwell=IDwell+1
enddo
c
c Echo input to iout file
c
IF ( IWELPT.EQ.0 ) THEN
IF ( nqreject.GT.0 ) THEN
txt = ' wells were outside of the model domain.'
WRITE (IOUT, '(1X,/,5x,i5,a50)') nqreject, txt
txt = 'The rejected pumpage totaled: '
WRITE (IOUT, '(1X,/1X,a34,g14.5)') txt, qreject
ENDIF
c
WRITE (IOUT, '(1X,/,10x,i5," MNW WELLS")') NWELL2
WRITE (IOUT, 9003)
9003 FORMAT (' No. Lay Row Col Stress QW param', 6x,
+ 'Rw Skin WL Limit WL Refer NonLinear Cp',
+ ' QW Group Cell-To-Well Min-Qoff Min-Qon',
+ ' Site Identifier')
c
DO m = 1, NWELL2
n = INT(WELL2(1, m))
k = (n-1)/(NCOL*NROW) + 1
j = MOD((n-1), NCOL*NROW)/NCOL + 1 !swm: note i,j, are switched
i = MOD((n-1), NCOL) + 1 !swm: from usual MF2K style
igrp = INT(WELL2(9, m))
c
rw = WELL2(5, m)
IF ( rw.LT.-ZERO25 ) THEN
cond = -rw
ELSE
qact = WELL2(3, m)
sk = WELL2(6, m)
cf = WELL2(16, m)
IF ( Iubcf.NE.0 ) cond = CEL2WELBCF(i,j,k,rw,sk,qact,cf)
IF ( Iulpf.NE.0 ) cond = CEL2WELLPF(i,j,k,rw,sk,qact,cf)
IF ( Iuhuf.NE.0 ) cond = CEL2WELHUF(i,j,k,rw,sk,qact,cf)
IF ( rw.LT.ZERO25 ) cond = cond*1.0D3
ENDIF
WELL2(11, m) = cond
c
c ---------Modified OUTPUT to hide internal pointers that "Look Funny" --KJH-- July 10, 2003
IF ( WELL2(8, m).LT.BIG ) THEN
hlim = WELL2(7, m)
hrfw = WELL2(8, m)
ELSE IF ( WELL2(7, m).LT.BIG ) THEN
ne = IFRL(WELL2(7, m))
hlim = WELL2(7, ne)
hrfw = WELL2(8, ne)
ENDIF
WRITE (IOUT, 9004) m, k, j, i, (WELL2(ii, m), ii=3, 6), hlim,
+ hrfw, WELL2(16, m), igrp, WELL2(11, m),
+ (WELL2(ii, m)*100.0D0, ii=13, 14),
+ MNWSITE(m)
9004 FORMAT (1x, 4I6, 6g11.4, g13.6, i10, g13.6, 2F10.3, 2x, a32)
c
ENDDO
ELSE
WRITE (IOUT, *) 'WELLS WILL NOT BE PRINTED'
ENDIF
c
c Write blank fields in Auxillary BYNODE file if KPER=1 & IO>0
c
IF ( TOTIM.LT.1E-26 .AND. IOWELL2(2).NE.0 ) THEN
io = ABS(IOWELL2(2))
DO m = 1, NWELL2
n = IFRL(WELL2(1, m))
WRITE (io, '(a32,1x,2i8)') MNWSITE(m), m, n
ENDDO
ENDIF
c
c Write blank fields in Auxillary QSUM file if KPER=1 & IO>0
c
IF ( TOTIM.LT.1E-26 .AND. IOWELL2(3).NE.0 ) THEN
io = ABS(IOWELL2(3))
m = 0
DO WHILE ( m.LT.NWELL2 )
m = m + 1
IF ( WELL2(8, m).GT.BIG ) THEN
ne = IFRL(WELL2(7, m))
WRITE (ABS(IOWELL2(3)), '(a32,1x,i5.5,"-",i5.5)') MNWSITE(m)
+ , m, ne
m = ne
ENDIF
ENDDO
ENDIF
c
END SUBROUTINE GWF2MNW17RP
c
c_________________________________________________________________________________
c
SUBROUTINE GWF2MNW17AD(Iubcf, Iulpf, Iuhuf, Igrid)
C VERSION 20020819 KJH
c
c----- MNW by K.J. Halford
c
c ******************************************************************
c Update Qact for wells that were constrained
c ******************************************************************
c
C SPECIFICATIONS:
C ------------------------------------------------------------------
USE GLOBAL, ONLY:NCOL,NROW,IBOUND,HNEW
USE GWFMNW1MODULE,ONLY:NWELL2,SMALL,WELL2,ZERO8,BIG
IMPLICIT NONE
INTRINSIC ABS, MOD
INTEGER, EXTERNAL :: IFRL
DOUBLE PRECISION, EXTERNAL :: CEL2WELBCF, CEL2WELLPF, CEL2WELHUF
c Arguments
INTEGER, INTENT(IN) :: Iubcf, Iuhuf, Iulpf, Igrid
c Local Variables
DOUBLE PRECISION :: rw, cond, qact, sk, cf, qoff, qon, qsmall
DOUBLE PRECISION :: qdes, csum, chsum, hwell, hlim, href, ipole
DOUBLE PRECISION :: ddmax, ddsim, qpot, ratio
INTEGER iin, m, n, ne, k, j, i
c ------------------------------------------------------------------
c-----SET POINTERS FOR THE CURRENT GRID.
CALL SGWF2MNW1PNT(Igrid)
c
c
c1------if number of wells <= 0 then return.
IF ( NWELL2.LE.0 ) RETURN
c
c Compute cell-to-well conductance for each well node
c
DO m = 1, NWELL2
n = IFRL(WELL2(1, m))
k = (n-1)/(NCOL*NROW) + 1
j = MOD((n-1),NCOL*NROW)/NCOL + 1 !swm: note i,j are switched
i = MOD((n-1),NCOL) + 1 !swm: from usual MF2K style
c-----if the cell is inactive or specified then bypass processing.
IF ( IBOUND(i,j,k).NE.0 ) THEN
rw = WELL2(5, m)
IF ( rw.LT.-ZERO8 ) THEN
cond = -rw
ELSE
qact = WELL2(3, m)
sk = WELL2(6, m)
cf = WELL2(16, m)
IF ( Iubcf.NE.0 ) cond = CEL2WELBCF(i,j,k,rw,sk,qact,cf)
IF ( Iulpf.NE.0 ) cond = CEL2WELLPF(i,j,k,rw,sk,qact,cf)
IF ( Iuhuf.NE.0 ) cond = CEL2WELHUF(i,j,k,rw,sk,qact,cf)
IF ( rw.LT.ZERO8 ) cond = cond*1.0D3
ENDIF
WELL2(11, m) = cond
ENDIF
ENDDO
c
c Allow constrained wells a new chance with the next time step
c
m = 0
DO WHILE ( m.LT.NWELL2 )
m = m + 1
qoff = WELL2(13, m)
qon = WELL2(14, m)
qact = WELL2(3, m)
qsmall = SMALL
c
c A very large # in WL reference array (8,m) triggers multi-node calculation
c
IF ( WELL2(8, m).GT.BIG ) THEN
c Compute hwell / Qpot for multi-node well
ne = IFRL(WELL2(7, m))
qdes = WELL2(15, ne)
csum = 0.0D0
chsum = 0.0D0
qact = 0.0D0
qsmall = SMALL*ABS(qdes)
DO iin = m, ne
n = IFRL(WELL2(1, iin))
k = (n-1)/(NCOL*NROW) + 1
j = MOD((n-1),NCOL*NROW)/NCOL + 1 !swm: note i,j are switched
i = MOD((n-1),NCOL) + 1 !swm: from usual MF2K style
IF ( IBOUND(i,j,k).NE.0 ) THEN
csum = csum + WELL2(11, iin)
chsum = chsum + WELL2(11, iin)*HNEW(i,j,k)
qact = qact + WELL2(3, iin)
ELSE
qact = 0.0D0
ENDIF
ENDDO
c---div0 --- CSUM could go to zero if the entire well is dry
IF ( csum.GT.ZERO8 ) THEN
hwell = (qdes+chsum)/csum
ELSE
hwell = HNEW(i,j,k)
ENDIF
m = ne
c Test DD constraints, Hlim is assumed to be a Max/Min for Injection/Production wells
ipole = 0.0D0
IF ( ABS(qdes).GT.ZERO8 ) ipole = qdes/ABS(qdes)
hlim = WELL2(7, ne)
href = WELL2(8, ne)
ddmax = ipole*(hlim-href)
ddsim = ipole*(hwell-href)
qpot = hlim*csum - chsum
IF ( ddsim.GT.ddmax ) THEN
hwell = hlim
qpot = hwell*csum - chsum
ENDIF
cond = csum
ELSE ! End of multi-node conditioning IF statement
c Compute hwell / Qpot for single-node well
n = IFRL(WELL2(1, m))
k = (n-1)/(NCOL*NROW) + 1
j = MOD((n-1),NCOL*NROW)/NCOL + 1 !swm: note i,j are switched
i = MOD((n-1),NCOL) + 1 !swm: from usual MF2K style
cond = WELL2(11, m)
hlim = WELL2(7, m)
qpot = (hlim-HNEW(i,j,k))*cond
qdes = WELL2(15, m)
ENDIF
c
c Compute ratio of potential/desired flow rates
ratio = 1.00D0
IF ( ABS(qdes).GT.SMALL ) ratio = qpot/qdes
IF ( ratio.GT.0.9999D0 ) THEN
ratio = 1.0D0
qpot = qdes
ENDIF
c Check if potential flow rate is below cutoff
IF ( ratio.LT.qoff ) THEN
qact = 0.0D0
qdes = qact
WELL2(2, m) = qdes
WELL2(3, m) = qact
c Check if potential flow rate is above restart threshold
ELSE IF ( ratio.GT.qon .AND. ABS(qact).LT.qsmall ) THEN
qdes = WELL2(15, m)
WELL2(2, m) = qdes
WELL2(3, m) = qpot
c ELSE
c Otherwise leave the flow rate alone
ENDIF
c
ENDDO ! End of overall test loop
c
END SUBROUTINE GWF2MNW17AD
c
c_________________________________________________________________________________
c
SUBROUTINE GWF2MNW17FM(Kiter, Iubcf, Iulpf, Iuhuf, Igrid)
c VERSION 20020819 KJH
c
c----- MNW by K.J. Halford
c
c ******************************************************************
c add well flow to source term
c ******************************************************************
c
C SPECIFICATIONS:
C ------------------------------------------------------------------
USE GLOBAL, ONLY:NCOL,NROW,IBOUND,HNEW,HCOF,RHS
USE GWFMNW1MODULE,ONLY:NWELL2,NOMOITER,SMALL,WELL2,ZERO20,BIG
IMPLICIT NONE
INTRINSIC ABS, MOD
INTEGER, EXTERNAL :: IFRL
DOUBLE PRECISION, EXTERNAL :: CEL2WELBCF, CEL2WELLPF, CEL2WELHUF
c Arguments
INTEGER, INTENT(IN) :: Iubcf, Iuhuf, Iulpf, Kiter, Igrid
c Local Variables
INTEGER :: iin, iqslv, m, n, ne, k, j, i
DOUBLE PRECISION :: rw, cond, qact, sk, cf, qdes, csum, chsum
DOUBLE PRECISION :: hwell, ipole, hlim, href, ddmax, ddsim, ratio
DOUBLE PRECISION :: dhc2w
c ------------------------------------------------------------------
c-----SET POINTERS FOR THE CURRENT GRID.
CALL SGWF2MNW1PNT(Igrid)
c
c CR( i, j, k) ------> CR i + 1/2
c CC( i, j, k) ------> CC j + 1/2
c CV( i, j, k) ------> CV k + 1/2
c
c1------if number of wells <= 0 then return.
IF ( NWELL2.LE.0 ) RETURN
c
c Compute cell-to-well conductance for each well node
c
DO m = 1, NWELL2
n = IFRL(WELL2(1, m))
k = (n-1)/(NCOL*NROW) + 1
j = MOD((n-1),NCOL*NROW)/NCOL + 1 !swm: note i,j are switched
i = MOD((n-1),NCOL) + 1 !swm: from usual MF2K style
c-----if the cell is inactive or specified then bypass processing.
IF ( IBOUND(i,j,k).NE.0 ) THEN
rw = WELL2(5, m)
IF ( rw.LT.-ZERO20 ) THEN
cond = -rw
ELSE
qact = WELL2(3, m)
sk = WELL2(6, m)
cf = WELL2(16, m)
IF ( Iubcf.NE.0 ) cond = CEL2WELBCF(i,j,k,rw,sk,qact,cf)
IF ( Iulpf.NE.0 ) cond = CEL2WELLPF(i,j,k,rw,sk,qact,cf)
IF ( Iuhuf.NE.0 ) cond = CEL2WELHUF(i,j,k,rw,sk,qact,cf)
IF ( rw.LT.ZERO20 ) cond = cond*1.0D3
ENDIF
WELL2(11, m) = cond
ENDIF
ENDDO
c
c Prepare components and limits of a multi-node well
m = 0
DO WHILE ( m.LT.NWELL2 )
m = m + 1
WELL2(10, m) = 1.0D31
c
c A very large # in WL reference array (8,m) triggers multi-node calculation
c
IF ( WELL2(8, m).GT.BIG ) THEN
ne = IFRL(WELL2(7, m))
qdes = WELL2(2, ne)
qact = qdes
csum = 0.0D0 !swm: why not initialize DP
chsum = 0.0D0 !swm: why not initialize DP
DO iin = m, ne
n = IFRL(WELL2(1, iin))
k = (n-1)/(NCOL*NROW) + 1
j = MOD((n-1),NCOL*NROW)/NCOL + 1 !swm: note i,j are switched
i = MOD((n-1),NCOL) + 1 !swm: from usual MF2K style
IF ( IBOUND(i,j,k).NE.0 ) THEN
csum = csum + WELL2(11, iin)
chsum = chsum + WELL2(11, iin)*HNEW(i,j,k)
ELSE
WELL2(3, iin) = 0.0D0 !swm: why not initialize DP
ENDIF
ENDDO
c---div0 --- CSUM could go to zero if the entire well is dry
IF ( csum.GT.ZERO20 ) THEN
hwell = (qact+chsum)/csum
ELSE
hwell = HNEW(i,j,k)
ENDIF
c
c Test DD constraints, Hlim is assumed to be a Max/Min for Injection/Production wells
ipole = 0.0D0
IF ( ABS(qdes).GT.ZERO20 ) ipole = qdes/ABS(qdes)
hlim = WELL2(7, ne)
href = WELL2(8, ne)
ddmax = ipole*(hlim-href)
ddsim = ipole*(hwell-href)
c
IF ( ddsim.GT.ddmax ) THEN
hwell = hlim
qact = hwell*csum - chsum
c DD constraints that stop production are not tested until after the 2nd iteration
IF ( Kiter.GT.2 ) THEN
ratio = 1.00D0
IF ( ABS(qdes).GT.SMALL ) ratio = qact/qdes
IF ( ratio.LT.0.00001 ) THEN
qact = 0.0D0
IF ( csum.GT.0.0 ) THEN
hwell = chsum/csum
ELSE
hwell = HNEW(i,j,k)
ENDIF
ENDIF
ENDIF
ENDIF
c
c Assign flow rates and water levels to individual nodes
DO iin = m, ne
n = IFRL(WELL2(1, iin))
k = (n-1)/(NCOL*NROW) + 1
j = MOD((n-1),NCOL*NROW)/NCOL + 1 !swm: note i,j are switched
i = MOD((n-1),NCOL) + 1 !swm: from usual MF2K style
WELL2(10, iin) = hwell
qact = (hwell-HNEW(i,j,k))*WELL2(11, iin)
WELL2(3, iin) = qact
ENDDO
m = ne
ENDIF ! End of multi-node conditioning IF statement
ENDDO ! End of overall multi-node test loop
C
C2------process each well in the well list.
m = 0
DO WHILE ( m.LT.NWELL2 )
m = m + 1
n = IFRL(WELL2(1, m))
k = (n-1)/(NCOL*NROW) + 1
j = MOD((n-1),NCOL*NROW)/NCOL + 1 !swm: note i,j are switched
i = MOD((n-1),NCOL) + 1 !swm: from usual MF2K style
qdes = WELL2(2, m)
c-----if the cell is inactive then bypass processing.
IF ( IBOUND(i,j,k).GT.0 ) THEN
qact = WELL2(3, m)
cond = WELL2(11, m)
c
hlim = WELL2(7, m)
href = WELL2(8, m)
IF ( WELL2(10, m).GT.BIG .AND. cond.GT.ZERO20 ) THEN
dhc2w = qact/cond
c Process single-node wells
c Test DD constraints, Hlim is assumed to be a Max/Min for Injection/Production wells
ipole = 0.0D0
IF ( ABS(qdes).GT.ZERO20 ) ipole = qdes/ABS(qdes)
hwell = HNEW(i,j,k) + dhc2w
WELL2(10, m) = hwell
ddsim = ipole*(hwell-href)
ddmax = ipole*(hlim-href) - SMALL
ratio = 1.00D0
IF ( ABS(qdes).GT.ZERO20 ) ratio = qact/qdes
IF ( ABS(ratio).GT.1.00 ) qact = qdes
IF ( ratio.LT.ZERO20 ) qact = 0.0D0
c Well will be simulated as a specified rate or GHB
iqslv = 0
IF ( ddsim.GT.ddmax .AND. ddmax.GT.ZERO20 ) iqslv = 1
IF ( (qdes-qact)**2.GT.SMALL ) iqslv = 1
IF ( ABS(qact).LT.ZERO20 .AND. ddsim.GT.ddmax ) iqslv = 0
IF ( ABS(qact).LT.ZERO20 .AND. ddsim.LT.ddmax ) iqslv = 1
IF ( ABS(qdes).LT.ZERO20 .OR. ratio.GT.1.0D0-ZERO20 )
+ iqslv = 0
c
ELSE IF ( cond.LT.ZERO20 ) THEN
qact = 0.0D0
iqslv = 0
c Process multi-node wells, Constraints were already tested when allocating flow
ELSE IF ( MOD(Kiter, 2).EQ.0 .AND. ABS(qact).GT.SMALL ) THEN
hlim = WELL2(10, m)
iqslv = 1
ELSE
qact = WELL2(3, m)
iqslv = 0
ENDIF
c
c Modify HCOF and RHS arrays
IF ( iqslv.NE.0 .AND. Kiter.GT.1 .AND. Kiter.LT.NOMOITER )THEN
qact = (hlim-HNEW(i,j,k))*cond
HCOF(i,j,k) = HCOF(i,j,k) - cond
RHS(i,j,k) = RHS(i,j,k) - cond*hlim
ELSE
c Specify Q and solve for head; add Q to RHS accumulator.
RHS(i,j,k) = RHS(i,j,k) - qact
ENDIF
WELL2(3, m) = qact
ENDIF
ENDDO ! End of DO WHILE loop
c
END SUBROUTINE GWF2MNW17FM
c
c_________________________________________________________________________________
c
SUBROUTINE GWF2MNW17BD(Nstp, Kstp, Kper, Igrid)
c VERSION 20030710 KJH
c
c----- MNW by K.J. Halford 1/31/98
c ******************************************************************
c calculate volumetric budget for wells
c ******************************************************************
c
c specifications:
c ------------------------------------------------------------------
USE GLOBAL, ONLY:NCOL,NROW,NLAY,IBOUND,BUFF,HNEW,IOUT
USE GWFBASMODULE,ONLY:DELT,PERTIM,TOTIM,ICBCFL,VBVL,VBNM,MSUM,HDRY
USE GWFMNW1MODULE,ONLY:NWELL2,PLOSS,MNWSITE,IWL2CB,IOWELL2,
1 WELL2,ZERO25,BIG
IMPLICIT NONE
INTRINSIC ABS, MOD
INTEGER, EXTERNAL :: IFRL
EXTERNAL UBDSV4, UBDSVB, UBUDSV
c Arguments
INTEGER, INTENT(IN) :: Nstp, Kstp, Kper, Igrid
c Local Variables
DOUBLE PRECISION :: ratin, ratout, qwsum, qsum, qwbar, drytest
DOUBLE PRECISION :: qd, hlim, href, hwell, dd, s, ipole, sNL, sL
DOUBLE PRECISION :: qin, qout, qwfsum, q
REAL :: dummy(5), qsing
INTEGER :: ibd, igrp1, igrp2, iin, imult, iobynd, ioc
INTEGER :: ioch, ioqsum, m, m2, n, naux, ne, nwelvl, k, i, j
CHARACTER(LEN=16) :: text, auxtxt(20)
c ------------------------------------------------------------------
c-----SET POINTERS FOR THE CURRENT GRID.
CALL SGWF2MNW1PNT(Igrid)
c
c ----+----1----+-
text = ' MNW'
c ------------------------------------------------------------------
c clear ratin and ratout accumulators.
ratin = 0.0D0 !swm: why not initialized DP
ratout = 0.0D0 !swm: why not initialized DP
ibd = 0
IF ( IWL2CB.GT.0 ) ibd = ICBCFL
C
C2-----IF CELL-BY-CELL FLOWS WILL BE SAVED AS A LIST, WRITE HEADER.
IF ( ibd.EQ.2 ) THEN
auxtxt = ' ' !rsr set auxtxt to blank strings
naux = 0 !! Set to zero -- Change order to dump
c IF ( IAUXSV.EQ.0 ) NAUX=0
CALL UBDSV4(Kstp, Kper, text, naux, auxtxt, IWL2CB, NCOL, NROW,
+ NLAY, NWELL2, IOUT, DELT, PERTIM, TOTIM, IBOUND)
ENDIF
c clear the buffer.
DO k = 1, NLAY
DO i = 1, NROW
DO j = 1, NCOL
Buff(j,i,k) = 0.0
ENDDO
ENDDO
ENDDO
c -----print the header for individual rates if requested(IWL2CB<0).
IF ( IWL2CB.LT.0 .AND. ICBCFL.NE.0 ) THEN
WRITE (IOUT, '(/,1x,a16," PERIOD =",i5,8h STEP =,i5)') text,
+ Kper, Kstp
WRITE (IOUT, 9001)
ENDIF
9001 FORMAT (' Entry LAY ROW COL', 9x, 'Q', 6x, 'H-Well', 7x,
+ 'H-Cell', 7x, 'DD ', 7x, 'QW-Avg', 6x, 's-LINEAR', 3x,
+ 's-NonLINEAR')
c
c Create WEL1 file if iowell2(1) > 0
IF ( IOWELL2(1).GT.0 .AND. Nstp.EQ.Kstp )
+ WRITE (IOWELL2(1), '(1i10)') NWELL2
c
c2------if there are no wells do not accumulate flow
IF ( NWELL2.GT.0 ) THEN
c
c Compute flow weighted QW values and store in well2(11,m)
c
DO m = 1, NWELL2
WELL2(11, m) = WELL2(3, m)*WELL2(4, m)
WELL2(12, m) = 0.0D0 !swm: why not initialized DP
IF ( WELL2(4, m).LT.0.00 .OR. WELL2(3, m).GT.0.00 ) THEN
WELL2(11, m) = -1
WELL2(12, m) = 1
ENDIF
ENDDO
c
DO m = 1, NWELL2
igrp1 = IFRL(WELL2(9, m))
IF ( WELL2(12, m).LT.0.5 ) THEN
qwsum = 0.0D0
qsum = 0.0D0
DO m2 = m, NWELL2
igrp2 = IFRL(WELL2(9, m2))
IF ( igrp1.EQ.igrp2 .AND. WELL2(12, m2).LT.0.5 ) THEN
qwsum = qwsum + WELL2(11, m2)
qsum = qsum + WELL2(3, m2)
WELL2(12, m2) = 1
ENDIF
ENDDO
c
qwbar = qwsum
IF ( qsum**2.GT.ZERO25 ) qwbar = qwsum/qsum
DO m2 = m, NWELL2
igrp2 = IFRL(WELL2(9, m2))
IF ( igrp1.EQ.igrp2 .AND. WELL2(4, m2).GE.0.0 )
+ WELL2(11, m2) = qwbar
ENDDO
ENDIF
ENDDO
c
imult = 0
Crsr added next line to be sure ioch has a value
ioch = 0
DO m = 1, NWELL2
n = IFRL(WELL2(1, m))
k = (n-1)/(NCOL*NROW) + 1
j = MOD((n-1),NCOL*NROW)/NCOL + 1 !swm: note i,j are switched
i = MOD((n-1),NCOL) + 1 !swm: from usual MF2K style
drytest = HNEW(i,j,k) - HDRY
IF ( ABS(drytest).LT.ZERO25 ) WELL2(3, m) = 0.0D0 !swm: why not initialized DP
q = WELL2(3, m)
WELL2(17, m) = q !!7/13/2003 - CZ: preserve q
c
c Report all wells with production less than the desired rate......
IF ( IBOUND(i,j,k).NE.0 .OR. ABS(drytest).LT.ZERO25 ) THEN
qd = WELL2(2, m)
hlim = WELL2(7, m)
c -----Modified OUTPUT to hide internal pointers that "Look Funny" in DD column--KJH-- July 10, 2003
IF ( WELL2(8, m).GT.BIG ) THEN
imult = 1
IF ( hlim.LT.BIG ) THEN
ne = IFRL(hlim)
href = WELL2(8, ne)
c ELSE
ENDIF
ELSE
href = WELL2(8, m)
ENDIF
hwell = WELL2(10, m)
qwbar = WELL2(11, m)
dd = hwell - href
c
ioch = 0
IF ( IWL2CB.LT.0 .AND. ICBCFL.NE.0 ) ioch = 1
c -----print the individual rates if requested(IWL2CB<0).
IF ( ioch.EQ.1 ) THEN
s = HNEW(i,j,k) - hwell
ipole = 0.0D0
IF ( ABS(s).GT.ZERO25 ) ipole = s/ABS(s)
sNL = ipole*WELL2(16, m)*ABS(q)**PLOSS
sL = s - sNL
WRITE (IOUT, '(i7,3i4,9g13.6)') m, k, j, i, q, hwell,
+ HNEW(i,j,k), dd, qwbar, sL, sNL
ENDIF
c
c -----print the individual rates to auxillary file if requested(IWL2CB<0).
iobynd = ABS(IOWELL2(2))
IF ( iobynd.GT.0 ) THEN
IF ( ioch.EQ.1 .OR. IOWELL2(2).LT.0 )
+ WRITE (iobynd, '(a32,1x,2i8,6g15.8)')
+ MNWSITE(m), m, n, TOTIM, q, hwell, HNEW(i,j,k), qwbar
ENDIF
c Create WEL1 file if iowell2(1) > 0
IF ( IOWELL2(1).GT.0 .AND. Nstp.EQ.Kstp )
+ WRITE(IOWELL2(1),'(i9,2i10,1X,g11.4,1X,i10,2x,6g11.4)')
+ k, j, i, q, 0, qd, hwell, HNEW(i,j,k), dd, href, qwbar
c
Buff(i,j,k) = Buff(i,j,k) + q
IF ( q.GE.0.0 ) THEN
c -----pumping rate is positive(recharge). add it to ratin.
ratin = ratin + q
ELSE
c -----pumping rate is negative(discharge). add it to ratout.
ratout = ratout - q
ENDIF
ENDIF
ENDDO
c
c Sum components of multi-node wells
c
c -----print the header for multi-node rates if requested(IWL2CB<0).
IF ( ioch.EQ.1 .AND. imult.EQ.1 ) THEN
WRITE (IOUT, '(/,5x," Multi-Node Rates & Average QW")')
WRITE (IOUT, 9002)
9002 FORMAT (' Site Identifier ', 5x, 'ENTRY: Begin - End', 2x,
+ 'Q-Total', 7x, 'H-Well', 7x, 'DD ', 7x, 'QW-Avg')
ENDIF
c
m = 0
DO WHILE ( m.LT.NWELL2 )
m = m + 1
IF ( WELL2(8, m).GT.BIG ) THEN
ne = IFRL(WELL2(7, m))
qwsum = 0.0D0
qwfsum = 0.0D0
qsum = 0.0D0
qin = 0.0D0
qout = 0.0D0
DO iin = m, ne
n = IFRL(WELL2(1, iin))
k = (n-1)/(NCOL*NROW) + 1
j = mod((n-1),NCOL*NROW)/NCOL + 1 !swm: note i,j are switched
i = mod((n-1),NCOL) + 1 !swm: from usual MF2K style
IF ( IBOUND(i,j,k).EQ.0 ) WELL2(3, iin) = 0.0D0
IF ( WELL2(4, iin).GE.0.0 .AND. WELL2(3, iin).LE.0.0 )THEN
qwfsum = qwfsum + WELL2(3, iin)
qwsum = qwsum + WELL2(3, iin)*WELL2(4, iin)
ENDIF
IF ( WELL2(3, iin).LE.0.0D0 ) THEN
qin = qin + WELL2(3, iin)
ELSE
qout = qout + WELL2(3, iin)
ENDIF
qsum = qsum + WELL2(3, iin)
WELL2(3, iin) = 0.0D0
ENDDO
WELL2(3, ne) = qsum
c -----print the summed rates if requested(IWL2CB<0).
qwbar = WELL2(4, ne)
IF ( qwfsum**2.GT.ZERO25 ) qwbar = qwsum/qwfsum
href = WELL2(8, ne)
hwell = WELL2(10, ne)
dd = hwell - href
IF ( ioch.EQ.1 ) WRITE (IOUT, '(A26,1x,2i6,6g13.6)')
+ MNWSITE(m), m, ne, qsum, hwell, dd,
+ qwbar
c -----print the summed rates to auxillary file if requested .
ioqsum = ABS(IOWELL2(3))
IF ( ioqsum.GT.0 ) THEN
IF ( ioch.EQ.1 .OR. IOWELL2(3).LT.0 ) THEN
WRITE (ioqsum, 9003) MNWSITE(m), m, ne, TOTIM, qin,
+ qout, qsum, hwell, qwbar
9003 FORMAT (A32, i6.5, '-', i5.5, 12g15.8)
ENDIF
ENDIF
m = ne
ENDIF
ENDDO
IF ( ioch.EQ.1 .AND. imult.EQ.1 ) WRITE (IOUT, *)
c
c ----- END MULTI-NODE reporting section -------------
c
c6------if cell-by-cell flows will be saved call ubudsv to record them
IF ( ABS(IWL2CB).GT.0 .AND. ICBCFL.NE.0 ) THEN !! BooBoo Fix--July 10,2003 KJH
ioc = ABS(IWL2CB)
IF ( ibd.EQ.2 ) THEN !! Write COMPACT budget
nwelvl = 1 !! Dummy value
DO m = 1, NWELL2
n = IFRL(WELL2(1, m))
qsing = WELL2(17, m)
CALL UBDSVB(ioc, NCOL, NROW, n, 1, 1, qsing, dummy,
+ nwelvl, naux, 5, IBOUND, NLAY)
ENDDO
ELSE !! Write full 3D array
CALL UBUDSV(Kstp, Kper, text, ioc, Buff, NCOL, NROW, NLAY,
+ IOUT)
ENDIF
ENDIF
ENDIF
c
c7------move rates into vbvl for printing by module bas1ot.
VBVL(3, MSUM) = ratin
VBVL(4, MSUM) = ratout
c
c8------move rates times time step length into vbvl accumulators.
VBVL(1, MSUM) = VBVL(1, MSUM) + ratin*DELT
VBVL(2, MSUM) = VBVL(2, MSUM) + ratout*DELT
c
c9------move budget term labels into vbnm for printing.
VBNM(MSUM) = text
c
c10-----increment budget term counter(msum).
MSUM = MSUM + 1
c
c11-----return
END SUBROUTINE GWF2MNW17BD
c
c_________________________________________________________________________________
c
SUBROUTINE GWF2MNW17OT(Igrid)
C VERSION 20020819 KJH
c
c ******************************************************************
c Sort well output into useful tables
c ******************************************************************
c
c specifications:
c ------------------------------------------------------------------
USE GWFMNW1MODULE,ONLY:NWELL2,MXWEL2,IOWELL2,WELL2
IMPLICIT NONE
INTRINSIC CHAR, ABS
INTEGER, EXTERNAL :: IFRL
EXTERNAL IOWELLOUT
c Arguments
INTEGER, INTENT(IN) :: Igrid
c Local Variables
DOUBLE PRECISION :: hwell, conc, qt, qin, qout, q, timein, hcell
DOUBLE PRECISION :: qsum, qwbar, timmult
INTEGER :: i, icnt, io, iobynd, iopt, ioqsum, iostart, iot, istop
INTEGER :: me, nb, ne, node
CHARACTER(LEN=1) :: tab
CHARACTER(LEN=32) :: temptag, tt, lasttag, eoftag
c ------------------------------------------------------------------
CALL SGWF2MNW1PNT(IGRID)
c
tab = CHAR(9)
iostart = 1000
eoftag = 'EndOfFile__EndOfFile__EndOfFile_'
c Set Flag for printing header info once
DO i = 1, MXWEL2
WELL2(16, i) = 0 !! 16 = Header Flag
ENDDO
c
c Site file names are constructed to be OUTname_MNWSITE.txt
c All info for a well are dumped as tab delimited output
c
c------------------------------------------------------------------
c The 16 rows of the well array store:
c Row # = Description
c------------------------------------------------------------------
c 1 = Well node locator
c 2 = Net Discharge
c 3 = Water level in wellbore
c 4 = Water Quality
c 5 = Qin ---------------MNW ONLY--------
c 6 = Qout
c 7 = Q-node / Net Discharge
c 8 = MN-Flag --- Number of nodes / well
c 9 = I/O unit for well output
c 16 = Header Flag Print= 0 / NoPrint = 1
c------------------------------------------------------------------
c
c Test auxillary output files for cleaning data sets
iobynd = ABS(IOWELL2(2))
IF ( iobynd.GT.0 ) THEN
WRITE (iobynd, '(a32)') eoftag
REWIND (iobynd)
READ (iobynd, '(a)')
ELSE
RETURN
ENDIF
c
ioqsum = ABS(IOWELL2(3))
IF ( ioqsum.GT.0 ) THEN
WRITE (ioqsum, '(a32)') eoftag
REWIND (ioqsum)
READ (ioqsum, '(a)')
ELSE
RETURN
ENDIF
c
NWELL2 = 0
icnt = 0
istop = 0
lasttag = 'NO-PRINT'
c
DO WHILE ( istop.EQ.0 )
READ (iobynd, '(a32,1x,2i8,6g15.8)') temptag, me, node, timein,
+ q, hwell, hcell, conc
c
c Test for output before accumulating INFO
IF ( lasttag(1:8).NE.'NO-PRINT' .AND. temptag.NE.lasttag ) THEN !! Output
iot = IFRL(WELL2(9, 1))
c Write a Header ?????
iopt = iot - iostart
IF ( IFRL(WELL2(16,iopt)).EQ.0 ) THEN
WELL2(16, iopt) = 1
IF ( icnt.GT.1 ) THEN
WRITE (iot,
+ '(a4,a1,a9,a1,a6,a1,a13,a1,a10,a1,a11,99(a1,a4,i7.7))'
+ ) 'TIME', tab, 'Discharge', tab, 'H-Well', tab,
+ 'Concentration', tab, 'Net-Inflow', tab,
+ 'Net-Outflow',
+ (tab, 'Node', IFRL(WELL2(1,i)), i=1, icnt)
ELSE
WRITE (iot, '(a4,a1,a9,a1,a6,a1,a13)') 'TIME', tab,
+ 'Discharge', tab, 'H-Well', tab, 'Concentration'
ENDIF
ENDIF
c END of "Write a Header" Section
hwell = WELL2(3, icnt)
conc = WELL2(4, icnt)
IF ( icnt.GT.1 ) THEN
qt = WELL2(7, 1)
qin = WELL2(5, 1)
qout = WELL2(6, 1)
WRITE (iot, '(99(g15.8,a1))') WELL2(10, 1), tab, qt, tab,
+ hwell, tab, conc, tab, qin, tab, qout,
+ (tab, WELL2(2, i), i=1, icnt)
ELSE
qt = WELL2(2, 1)
WRITE (iot, '(99(g15.8,a1))') WELL2(10, 1), tab, qt, tab,
+ hwell, tab, conc
c
ENDIF
icnt = 0 !! RESET node counter
ENDIF
c Is this the EOF?
IF ( temptag.EQ.eoftag ) istop = 1
c
c Skip if this is a NO-PRINT node
IF ( temptag(1:8).EQ.'NO-PRINT' .OR. temptag.EQ.eoftag ) THEN
icnt = 0
ELSE
icnt = icnt + 1
c Identify pointer
CALL IOWELLOUT(temptag, iostart, io)
WELL2(1, icnt) = node !! 1 = Well node locator
WELL2(2, icnt) = q !! 2 = Net Discharge
WELL2(3, icnt) = hwell !! 3 = Water level in wellbore
WELL2(4, icnt) = conc !! 4 = Water Quality
WELL2(8, 1) = icnt !! 8 = MN-Flag --- Number of nodes / well
WELL2(9, 1) = io + iostart !! 9 = IO output
WELL2(10, 1) = timein !! 10 = Time
c
c Read MN well output if available
IF ( temptag.EQ.lasttag ) THEN !! MN well
IF ( icnt.EQ.2 .AND. ioqsum.GT.0 ) THEN
READ (ioqsum, 9001) tt, nb, ne, timmult, qin, qout, qsum,
+ hwell, qwbar
9001 FORMAT (A32, i6.5, i6.5, 12g15.8)
WELL2(4, 1) = qwbar !! 4 = Water Quality
WELL2(5, 1) = qin !! 5 = Qin ---------------MNW ONLY--------
WELL2(6, 1) = qout !! 6 = Qout
WELL2(7, 1) = qsum !! 7 = Qnet
ENDIF
ENDIF
ENDIF
c
c Save Value of TEMPTAG for comparison
lasttag = temptag
ENDDO
c
c Add IO close routine here if needed
c
END SUBROUTINE GWF2MNW17OT
c
c ******************************************************************
c ******************************************************************
SUBROUTINE IOWELLOUT(Temptag, Iostart, Io)
USE GWFMNW1MODULE, ONLY : NWELL2,MNWSITE,MNWNAME
IMPLICIT NONE
c Arguments
INTEGER, INTENT(IN) :: Iostart
INTEGER, INTENT(OUT) :: Io
CHARACTER(LEN=32), INTENT(IN) :: Temptag
c ------------------------------------------------------------------
c Local Variables
INTEGER :: i, k1, k2
CHARACTER(LEN=256) :: txt
c ------------------------------------------------------------------
i = 0
Io = 0
DO WHILE ( i.LT.NWELL2 )
i = i + 1
IF ( MNWSITE(i).EQ.Temptag ) THEN
Io = i
i = NWELL2
ENDIF
ENDDO
c
IF ( Io.EQ.0 ) THEN
NWELL2 = NWELL2 + 1
MNWSITE(NWELL2) = Temptag
Io = NWELL2
c Build output file name and Open file
k1 = INDEX(MNWNAME, ' ') - 1
k2 = INDEX(Temptag, ' ') - 1
IF ( k2.EQ.0 .AND. Temptag(32:32).NE.' ' ) k2 = 32
txt = MNWNAME(1:k1)//'.'//Temptag(1:k2)//'.txt'
OPEN (Io+Iostart, FILE=txt)
ENDIF
c
END SUBROUTINE IOWELLOUT
c
c_________________________________________________________________________________
c
DOUBLE PRECISION FUNCTION CEL2WELBCF(Ix, Iy, Iz, Rw, Skin, Q, Cf)
C VERSION 20030327 KJH -- Patched Hyd.K term in LPF solution
c
c----- MNW by K.J. Halford
c
c ******************************************************************
c Compute conductance term to define head loss from cell to wellbore
c Methodology is described in full by Peaceman (1983)
cswm: NOTE: MODIFIED FOR USE WITH THE BCF PACKAGE
c ******************************************************************
C Note: BCF, when LAYCON=0 or 2, does not save cell-by-cell
C Transmissivity (T) values. Instead, it converts the cell-by-cell
C T values to branch conductances CR and CC, using harmonic
C averaging. When BCF is used, the method used in this routine to
C generate cell-specific values of tx and ty is an approximation
C based on CR and CC. When LPF or HUF is used, cell-by-cell
C hydraulic-conductivity values are stored, this approximation is
C not needed, and the values generated for tx and ty are exact --
C ERB 1/29/01.
C
C SPECIFICATIONS::
C ------------------------------------------------------------------
USE GLOBAL, ONLY:NCOL,NROW,LAYHDT,DELR,DELC,BOTM,LBOTM,CR,CC,
1 HNEW
USE GWFBASMODULE,ONLY:HDRY
USE GWFBCFMODULE,ONLY:HY,TRPY,LAYCON
USE GWFMNW1MODULE,ONLY:PLOSS,SMALL,TWOPI,ZERO25
c
IMPLICIT NONE
INTRINSIC LOG, ABS, SQRT
c Arguments
INTEGER, INTENT(IN) :: Ix, Iy, Iz
DOUBLE PRECISION, INTENT(IN) :: Rw, Skin, Q, Cf
c Local Variables
DOUBLE PRECISION :: ro, ah, tempKX, dx, dy, top, bot, dxp, dxm
DOUBLE PRECISION :: txm, txp, dyp, dym, typ, tym, div, txx, tyy
DOUBLE PRECISION :: thick, upper, yx4, xy4, tpi2, a, b, c, cel2wel
C ------------------------------------------------------------------
!1000 FORMAT(/1X,
! &'***ERROR: MNW PACKAGE DOES NOT SUPPORT HEAD-DEPENDENT',/,
! &' THICKNESS OPTION OF SELECTED FLOW PACKAGE',/,
! &' (MNW DOES FULLY SUPPORT BCF, LPF, AND HUF PACKAGES)',/,
! &' -- STOP EXECUTION (CEL2WEL)')
C
dx = DELR(Ix)
dy = DELC(Iy)
top = BOTM(Ix, Iy, LBOTM(Iz)-1)
bot = BOTM(Ix, Iy, LBOTM(Iz))
C
C FIND HORIZONTAL ANISOTROPY, THE RATIO Ky/Kx
ah = TRPY(Iz)
C
IF ( LAYHDT(Iz).EQ.0 ) THEN
C THICKNESS IS NOT HEAD-DEPENDENT
dxp = dx
txp = 0.0D0
IF ( Ix.LT.NCOL ) THEN
dxp = DELR(Ix+1)
txp = CR(Ix, Iy, Iz)*(dx+dxp) / 2.0D0
ENDIF
dxm = dx
txm = txp
IF ( Ix.GT.1 ) THEN
dxm = DELR(Ix-1)
txm = CR(Ix-1, Iy, Iz)*(dx+dxm) / 2.0D0
ENDIF
IF ( txp.LT.SMALL ) txp = txm
IF ( txm.LT.SMALL ) txm = txp
c
dyp = dy
typ = 0.0D0
IF ( Iy.LT.NROW ) THEN
dyp = DELC(Iy+1)
typ = CC(Ix, Iy, Iz)*(dy+dyp) / 2.0D0
ENDIF
dym = dy
tym = typ
IF ( Iy.GT.1 ) THEN
dym = DELC(Iy-1)
tym = CC(Ix, Iy-1, Iz)*(dy+dym) / 2.0D0
ENDIF
IF ( typ.LT.SMALL ) typ = tym
IF ( tym.LT.SMALL ) tym = typ
txp = txp / dy
txm = txm / dy
typ = typ / dx
tym = tym / dx
c
c Eliminate zero values .....
c
IF ( typ.LT.SMALL .OR. NROW.LT.2 ) THEN
typ = txp
tym = txm
ENDIF
c
IF ( txp.LT.SMALL .OR. NCOL.LT.2 ) THEN
txp = typ
txm = tym
ENDIF
c
c Assuming expansion of grid is slight, if present, & that txx and tyy of the adjacent
c cells are about the same value.
txx = 0.0D0
div = txp + txm
IF ( div.GT.SMALL ) txx = 2.0D0*txp*txm / div
tyy = 0.0D0
div = typ + tym
IF ( div.GT.SMALL ) tyy = 2.0D0*typ*tym / div
IF ( txx.GT.SMALL .AND. tyy.LT.SMALL ) tyy = txx
IF ( tyy.GT.SMALL .AND. txx.LT.SMALL ) txx = tyy
ELSE
C THICKNESS IS HEAD-DEPENDENT
c Estimate T to well in an unconfined system
c
upper = HNEW(Ix, Iy, Iz)
tempKX = HY(Ix, Iy, Iz) !! BCF Hydraulic Conductivity array
IF ( LAYCON(Iz).EQ.3 ) THEN
IF ( upper.GT.top ) upper = top
ENDIF
thick = upper - bot
c set thickness / conductance to 0 if cell is dry
IF ( (HNEW(Ix,Iy,Iz)-HDRY)**2.0D0.LT.ZERO25 ) thick = 0.0D0
txx = tempKX*thick
IF ( txx.LT.ZERO25 ) txx = 0.0D0
tyy = txx*ah
ENDIF
c
IF ( Rw.LT.ZERO25 .OR. txx.LT.ZERO25 .OR. tyy.LT.ZERO25 ) THEN
cel2wel = SQRT( txx*tyy )
ELSE
yx4 = SQRT(SQRT(tyy/txx))
xy4 = SQRT(SQRT(txx/tyy))
ro = 0.28D0*SQRT((yx4*dx)**2.0D0 + (xy4*dy)**2.0D0) / (yx4+xy4)
c
tpi2 = TWOPI*SQRT(txx*tyy)
a = LOG(ro/Rw) / tpi2
IF ( PLOSS.GT.0.99D0 ) THEN
b = Skin
c = Cf*ABS(Q)**(PLOSS-1.0D0)
ELSE
b = Skin / tpi2
c = 0.0D0
ENDIF
cel2wel = 1.0D0 / (a + b + c)
ENDIF
c
CEL2WELBCF = cel2wel
END FUNCTION CEL2WELBCF
c
c_________________________________________________________________________________
c
DOUBLE PRECISION FUNCTION CEL2WELLPF(Ix, Iy, Iz, Rw, Skin, Q, Cf)
C VERSION 20030327 KJH -- Patched Hyd.K term in LPF solution
c
c----- MNW by K.J. Halford
c
c ******************************************************************
c Compute conductance term to define head loss from cell to wellbore
c Methodology is described in full by Peaceman (1983)
cswm: NOTE: MODIFIED FOR USE WITH THE LPF PACKAGE
c ******************************************************************
C Note: BCF, when LAYCON=0 or 2, does not save cell-by-cell
C Transmissivity (T) values. Instead, it converts the cell-by-cell
C T values to branch conductances CR and CC, using harmonic
C averaging. When BCF is used, the method used in this routine to
C generate cell-specific values of tx and ty is an approximation
C based on CR and CC. When LPF or HUF is used, cell-by-cell
C hydraulic-conductivity values are stored, this approximation is
C not needed, and the values generated for tx and ty are exact --
C ERB 1/29/01.
C
C SPECIFICATIONS:
C ------------------------------------------------------------------
USE GLOBAL, ONLY:LAYHDT,DELR,DELC,BOTM,LBOTM,HNEW
USE GWFBASMODULE,ONLY:HDRY
USE GWFLPFMODULE,ONLY:HK,CHANI,HANI
USE GWFMNW1MODULE,ONLY:PLOSS,TWOPI,ZERO25
IMPLICIT NONE
INTRINSIC LOG, ABS, SQRT
c Arguments
INTEGER, INTENT(IN) :: Ix, Iy, Iz
DOUBLE PRECISION, INTENT(IN) :: Rw, Skin, Q, Cf
c Local Variables
DOUBLE PRECISION :: ro, ah, tempKX, dx, dy, top, bot, txx, tyy
DOUBLE PRECISION :: thick, upper, yx4, xy4, tpi2, a, b, c, cel2wel
C ------------------------------------------------------------------
!1000 FORMAT(/1X,
! &'***ERROR: MNW PACKAGE DOES NOT SUPPORT HEAD-DEPENDENT',/,
! &' THICKNESS OPTION OF SELECTED FLOW PACKAGE',/,
! &' (MNW DOES FULLY SUPPORT BCF, LPF, AND HUF PACKAGES)',/,
! &' -- STOP EXECUTION (CEL2WEL)')
C
dx = DELR(Ix)
dy = DELC(Iy)
top = BOTM(Ix, Iy, LBOTM(Iz)-1)
bot = BOTM(Ix, Iy, LBOTM(Iz))
C
C FIND HORIZONTAL ANISOTROPY, THE RATIO Ky/Kx
IF ( CHANI(Iz).GT.0.0 ) THEN
ah = CHANI(Iz)
ELSE
ah = HANI(Ix, Iy, Iz)
ENDIF
C
IF ( LAYHDT(Iz).EQ.0 ) THEN
C THICKNESS IS NOT HEAD-DEPENDENT
thick = top - bot
txx = HK(Ix, Iy, Iz)*thick
tyy = txx*ah
ELSE
C THICKNESS IS HEAD-DEPENDENT
c Estimate T to well in an unconfined system
c
upper = HNEW(Ix, Iy, Iz)
IF ( upper.GT.top ) upper = top
tempKX = HK(Ix, Iy, Iz) !! LPF Hydraulic Conductivity array
thick = upper - bot
c set thickness / conductance to 0 if cell is dry
IF ( (HNEW(Ix,Iy,Iz)-HDRY)**2.0D0.LT.ZERO25 ) thick = 0.0D0
txx = tempKX*thick
IF ( txx.LT.ZERO25 ) txx = 0.0D0
tyy = txx*ah
ENDIF
c
IF ( rw.LT.ZERO25 .OR. txx.LT.ZERO25 .OR. tyy.LT.ZERO25 ) THEN
cel2wel = SQRT(txx*tyy)
ELSE
yx4 = SQRT(SQRT(tyy/txx))
xy4 = SQRT(SQRT(txx/tyy))
ro = 0.28D0*SQRT((yx4*dx)**2.0D0 +(xy4*dy)**2.0D0) / (yx4+xy4)
c
tpi2 = TWOPI*SQRT(txx*tyy)
a = LOG(ro/rw) / tpi2
IF ( PLOSS.GT.0.99D0 ) THEN
b = Skin
c = Cf*ABS(Q)**(PLOSS-1.0D0)
ELSE
b = Skin / tpi2
c = 0.0D0
ENDIF
cel2wel = 1.0D0 / (a + b + c)
ENDIF
c
CEL2WELLPF = cel2wel
END FUNCTION CEL2WELLPF
c
c_________________________________________________________________________________
c
DOUBLE PRECISION FUNCTION CEL2WELHUF(Ix, Iy, Iz, Rw, Skin, Q, Cf)
C VERSION 20030327 KJH -- Patched Hyd.K term in LPF solution
c
c----- MNW by K.J. Halford
c
c ******************************************************************
c Compute conductance term to define head loss from cell to wellbore
c Methodology is described in full by Peaceman (1983)
cswm: NOTE: MODIFIED FOR USE WITH THE HUF PACKAGE
c ******************************************************************
C Note: BCF, when LAYCON=0 or 2, does not save cell-by-cell
C Transmissivity (T) values. Instead, it converts the cell-by-cell
C T values to branch conductances CR and CC, using harmonic
C averaging. When BCF is used, the method used in this routine to
C generate cell-specific values of tx and ty is an approximation
C based on CR and CC. When LPF or HUF is used, cell-by-cell
C hydraulic-conductivity values are stored, this approximation is
C not needed, and the values generated for tx and ty are exact --
C ERB 1/29/01.
C
C SPECIFICATIONS:
C ------------------------------------------------------------------
USE GLOBAL, ONLY:LAYHDT,DELR,DELC,BOTM,LBOTM,HNEW
USE GWFBASMODULE,ONLY:HDRY
USE GWFHUFMODULE,ONLY:HK,HKCC
USE GWFMNW1MODULE,ONLY:PLOSS,TWOPI,ZERO25
IMPLICIT NONE
INTRINSIC LOG, ABS, SQRT
c Arguments
INTEGER, INTENT(IN) :: Ix, Iy, Iz
DOUBLE PRECISION, INTENT(IN) :: Rw, Skin, Q, Cf
c Local Variables
DOUBLE PRECISION :: ro, ah, tempKX, dx, dy, top, bot, txx, tyy, ky
DOUBLE PRECISION :: thick, upper, yx4, xy4, tpi2, a, b, c, cel2wel
C ------------------------------------------------------------------
!1000 FORMAT(/1X,
! &'***ERROR: MNW PACKAGE DOES NOT SUPPORT HEAD-DEPENDENT',/,
! &' THICKNESS OPTION OF SELECTED FLOW PACKAGE',/,
! &' (MNW DOES FULLY SUPPORT BCF, LPF, AND HUF PACKAGES)',/,
! &' -- STOP EXECUTION (CEL2WEL)')
C
dx = DELR(Ix)
dy = DELC(Iy)
top = BOTM(Ix, Iy, LBOTM(Iz)-1)
bot = BOTM(Ix, Iy, LBOTM(Iz))
C
C FIND HORIZONTAL ANISOTROPY, THE RATIO Ky/Kx
tempKX = HK(Ix, Iy, Iz)
ky = HKCC(Ix, Iy, Iz)
ah = ky/tempKX
C
IF ( LAYHDT(Iz).EQ.0 ) THEN
C THICKNESS IS NOT HEAD-DEPENDENT
thick = top - bot
txx = HK(Ix, Iy, Iz)*thick
tyy = txx*ah
ELSE
C THICKNESS IS HEAD-DEPENDENT
c Estimate T to well in an unconfined system
c
upper = hnew(Ix, Iy, Iz)
IF ( upper.GT.top ) upper = top
tempKX = hk(Ix, Iy, Iz) !! HUF Hydraulic Conductivity array
thick = upper - bot
c set thickness / conductance to 0 if cell is dry
IF ( (hnew(Ix, Iy, Iz)-HDRY )**2.0D0.LT.ZERO25 ) thick = 0.0D0
txx = tempKX*thick
IF ( txx.LT.ZERO25 ) txx = 0.0D0
tyy = txx*ah
ENDIF
c
IF ( rw.LT.ZERO25 .OR. txx.LT.ZERO25 .OR. tyy.LT.ZERO25 ) THEN
cel2wel = SQRT( txx*tyy )
ELSE
yx4 = SQRT(SQRT(tyy/txx))
xy4 = SQRT(SQRT(txx/tyy))
ro = 0.28D0*SQRT((yx4*dx)**2.0D0 + (xy4*dy)**2.0D0) / (yx4+xy4)
c
tpi2 = TWOPI*SQRT(txx*tyy)
a = LOG(ro/rw) / tpi2
IF ( PLOSS.GT.0.99D0 ) THEN
b = Skin
c = Cf*ABS(Q)**(PLOSS-1.0D0)
ELSE
b = Skin / tpi2
c = 0.0D0
ENDIF
cel2wel = 1.0D0 / (a + b + c)
ENDIF
c
CEL2WELHUF = cel2wel
END FUNCTION CEL2WELHUF
c
c ******************************************************************
c Define direction of pointer along a row, column, or layer
c ******************************************************************
INTEGER FUNCTION IDIRECT(N1, N2, Ncol, Nrow)
IMPLICIT NONE
INTRINSIC ABS
c Arguments
INTEGER, INTENT(IN) :: N1, N2, Ncol, Nrow
c ------------------------------------------------------------------
IDIRECT = Ncol
IF ( ABS(N2-N1).GT.Ncol*Nrow ) IDIRECT = Ncol*Nrow
IF ( ABS(N2-N1).LT.Ncol ) IDIRECT = 1
IF ( N2.LT.N1 ) IDIRECT = -IDIRECT
c
END FUNCTION IDIRECT
c
c ******************************************************************
c ******************************************************************
! INTEGER FUNCTION ITXEND(Txt)
! IMPLICIT NONE
c Arguments
! CHARACTER(LEN=256), INTENT(IN) :: Txt
c Local Variables
! INTEGER :: k
c ------------------------------------------------------------------
! k = 256
! DO WHILE ( Txt(k:k).EQ.' ' .AND. k.GT.1 )
! k = k - 1
! ENDDO
! ITXEND = k
c
! END FUNCTION ITXEND
c
c ******************************************************************
c ******************************************************************
INTEGER FUNCTION IFRL(R)
IMPLICIT NONE
INTRINSIC ABS
c Arguments
DOUBLE PRECISION, INTENT(IN) :: R
c Local Variables
INTEGER :: ip
c ------------------------------------------------------------------
ip = ABS(R) + 0.5D0
IF ( R.LT.0.0D0 ) ip = -ip
IFRL = ip
END FUNCTION IFRL
c
c ******************************************************************
c NCREAD: reads lines of input and ignores lines that begin with a "#" sign.
c All information after a ! is wiped from the input card.
c ******************************************************************
SUBROUTINE NCREAD(Io, Txt, Ierr)
IMPLICIT NONE
EXTERNAL UPCASE, USTOP
c Arguments
INTEGER, INTENT(INOUT) :: Io
INTEGER, INTENT(OUT) :: Ierr
CHARACTER(LEN=256), INTENT(OUT) :: Txt
c Local Variables
INTEGER :: ioalt, ioflip, iohold, ki
CHARACTER(LEN=128) :: afile
CHARACTER(LEN=256) :: tx2
DATA ioflip, ioalt/69, 69/
c ------------------------------------------------------------------
Ierr = 0
5 READ (Io, '(a)', END=10) Txt
IF ( Txt(1:1).EQ.'#' ) GOTO 5
c
ki = INDEX(Txt, '!')
IF ( ki.GT.0 )
+ Txt(ki:256) = ' '
c
tx2 = Txt
CALL UPCASE(tx2)
c
c Test for switching control to an auxillary input file
c
ki = INDEX(Txt, ':')
IF ( INDEX(tx2, 'REDIRECT').GT.0 .AND. ki.GT.0 ) THEN
afile = Txt(ki+1:256)
ki = INDEX(afile, ' ') - 1
iohold = Io
Io = ioflip
ioflip = iohold
OPEN (Io, FILE=afile(1:ki), STATUS='OLD', ERR=20)
GOTO 5
ENDIF
c
c Test for returning io control from auxillary input to master input file
c
IF ( INDEX(tx2, 'RETURN').GT.0 .AND.
+ INDEX(tx2, 'CONTROL').GT.0 ) GOTO 10
c
ki = INDEX(tx2, '')
IF ( ki.GT.0 ) THEN
Ierr = 1
Txt(ki+5:256) = ' '
ENDIF
c
IF ( INDEX(tx2, '').GT.0 ) Ierr = 2
RETURN
c
c Report error in opening auxillary input file and stop
c
20 WRITE (*, 25) afile
25 FORMAT (/, ' ERROR opening auxillary input file', //,
+ ' The file: ', a40, ' does not exist', /)
c
c When compiling MNW with Modflow-96, comment out the call to
c USTOP and uncomment the STOP statement
CALL USTOP(' ')
c STOP
c
10 Txt(1:3) = 'EOF'
IF ( Io.EQ.ioalt ) THEN
CLOSE (Io)
iohold = Io
Io = ioflip
ioflip = iohold
GOTO 5
ELSE
Ierr = -1
ENDIF
c
END SUBROUTINE NCREAD
c
c ******************************************************************
c ******************************************************************
SUBROUTINE QREAD(R, Ni, Ain, Ierr)
IMPLICIT NONE
INTRINSIC CHAR, INDEX
INTEGER, PARAMETER :: MRNV=25
c Arguments
DOUBLE PRECISION, INTENT(OUT), DIMENSION(MRNV) :: R
INTEGER, INTENT(IN) :: Ni
INTEGER, INTENT(OUT) :: Ierr
CHARACTER(LEN=256), INTENT(IN) :: Ain
c Local Variables
INTEGER :: i, istat, ki, n, nd
CHARACTER(LEN=1) :: tab
CHARACTER(LEN=8) :: rdfmt
CHARACTER(LEN=256) :: a256
c ------------------------------------------------------------------
Ierr = 0
tab = CHAR(9) ! sets tab delimiter
c
c r(ni+1) records the number of non-numeric entries that were attempted to be read as a number
c r(ni+2) records the last column that was read from the card
c
R(Ni+1) = -1.0D0
a256 = Ain
DO i = 1, 256
IF ( a256(i:i).EQ.tab ) a256(i:i) = ' '
IF ( a256(i:i).EQ.',' ) a256(i:i) = ' '
IF ( a256(i:i).EQ.':' ) a256(i:i) = ' '
IF ( a256(i:i).EQ.'=' ) a256(i:i) = ' '
ENDDO
n = 1
i = 0
11 R(Ni+1) = R(Ni+1) + 1.0D0
10 i = i + 1
IF ( i.GE.256 ) GOTO 15
IF ( a256(i:i).EQ.' ' ) THEN
a256(i:i) = '?'
GOTO 10
ENDIF
c
ki = INDEX(a256, ' ') - 1
nd = ki - i + 1
rdfmt = '(F??.0) '
WRITE (rdfmt(3:4), '(i2.2)') nd
CERB Fix for bug that caused i to be incremented by only 1 position
CERB each time the read statement returns an error. This bug also
CERB incremented r(ni+1) unnecessarily. With Lahey-compiled code, the
CERB buggy version would read a final E in a word (without returning an
CERB error) as a zero.
CERB read (a256(i:ki),rdfmt,err=11,end=10) r(n)
READ (a256(i:ki), rdfmt, ERR=13, IOSTAT=istat) R(n)
13 CONTINUE
i = ki
IF ( istat.GT.0 ) GOTO 11 ! PART OF BUG FIX -- ERB
n = n + 1
IF ( n.LE.Ni .AND. i.LT.256 ) GOTO 10
c
15 n = n - 1
Ierr = Ni - n
R(Ni+2) = i
c
END SUBROUTINE QREAD
C***********************************************************************
SUBROUTINE GWF2MNW17DA(Igrid)
C ******************************************************************
C DEALLOCATE MNW DATA
C ******************************************************************
C ******************************************************************
C
C SPECIFICATIONS:
C ------------------------------------------------------------------
USE GWFMNW1MODULE
C ------------------------------------------------------------------
C Arguments
INTEGER :: Igrid, IDUM
C ------------------------------------------------------------------
IDUM=IGRID
DEALLOCATE (GWFMNWDAT(Igrid)%NWELL2)
DEALLOCATE (GWFMNWDAT(Igrid)%MXWEL2)
DEALLOCATE (GWFMNWDAT(Igrid)%IWL2CB)
DEALLOCATE (GWFMNWDAT(Igrid)%NOMOITER)
DEALLOCATE (GWFMNWDAT(Igrid)%KSPREF)
DEALLOCATE (GWFMNWDAT(Igrid)%IWELPT)
DEALLOCATE (GWFMNWDAT(Igrid)%PLOSS)
DEALLOCATE (GWFMNWDAT(Igrid)%SMALL)
DEALLOCATE (GWFMNWDAT(Igrid)%HMAX)
DEALLOCATE (GWFMNWDAT(Igrid)%MNWNAME)
DEALLOCATE (GWFMNWDAT(Igrid)%IOWELL2)
DEALLOCATE (GWFMNWDAT(Igrid)%HREF)
DEALLOCATE (GWFMNWDAT(Igrid)%WELL2)
DEALLOCATE (GWFMNWDAT(Igrid)%MNWSITE)
if (associated(gwfmnwdat(igrid)%demandbuff))
1 deallocate (gwfmnwdat(igrid)%demandbuff)
C
END SUBROUTINE GWF2MNW17DA
C***********************************************************************
SUBROUTINE SGWF2MNW1PNT(Igrid)
C ******************************************************************
C SET MNW POINTER DATA TO CURRENT GRID
C ******************************************************************
C
C SPECIFICATIONS:
C ------------------------------------------------------------------
USE GWFMNW1MODULE
C ------------------------------------------------------------------
C Arguments
INTEGER :: Igrid
C ------------------------------------------------------------------
NWELL2=>GWFMNWDAT(Igrid)%NWELL2
MXWEL2=>GWFMNWDAT(Igrid)%MXWEL2
IWL2CB=>GWFMNWDAT(Igrid)%IWL2CB
NOMOITER=>GWFMNWDAT(Igrid)%NOMOITER
KSPREF=>GWFMNWDAT(Igrid)%KSPREF
IWELPT=>GWFMNWDAT(Igrid)%IWELPT
PLOSS=>GWFMNWDAT(Igrid)%PLOSS
SMALL=>GWFMNWDAT(Igrid)%SMALL
HMAX=>GWFMNWDAT(Igrid)%HMAX
MNWNAME=>GWFMNWDAT(Igrid)%MNWNAME
IOWELL2=>GWFMNWDAT(Igrid)%IOWELL2
HREF=>GWFMNWDAT(Igrid)%HREF
WELL2=>GWFMNWDAT(Igrid)%WELL2
MNWSITE=>GWFMNWDAT(Igrid)%MNWSITE
demandbuff=>gwfmnwdat(igrid)%demandbuff ! DLT
C
END SUBROUTINE SGWF2MNW1PNT
C***********************************************************************
SUBROUTINE SGWF2MNW1PSV(Igrid)
C ******************************************************************
C SAVE MNW POINTER DATA
C ******************************************************************
C
C SPECIFICATIONS:
C ------------------------------------------------------------------
USE GWFMNW1MODULE
C ------------------------------------------------------------------
C Arguments
INTEGER :: Igrid
C ------------------------------------------------------------------
GWFMNWDAT(Igrid)%NWELL2=>NWELL2
GWFMNWDAT(Igrid)%MXWEL2=>MXWEL2
GWFMNWDAT(Igrid)%IWL2CB=>IWL2CB
GWFMNWDAT(Igrid)%NOMOITER=>NOMOITER
GWFMNWDAT(Igrid)%KSPREF=>KSPREF
GWFMNWDAT(Igrid)%IWELPT=>IWELPT
GWFMNWDAT(Igrid)%PLOSS=>PLOSS
GWFMNWDAT(Igrid)%SMALL=>SMALL
GWFMNWDAT(Igrid)%HMAX=>HMAX
GWFMNWDAT(Igrid)%MNWNAME=>MNWNAME
GWFMNWDAT(Igrid)%IOWELL2=>IOWELL2
GWFMNWDAT(Igrid)%HREF=>HREF
GWFMNWDAT(Igrid)%WELL2=>WELL2
GWFMNWDAT(Igrid)%MNWSITE=>MNWSITE
gwfmnwdat(igrid)%demandbuff=>demandbuff ! dlt
C
END SUBROUTINE SGWF2MNW1PSV