MODFLOW 6  version 6.9.0.dev0
USGS Modular Hydrologic Model
gwfnpfmodule Module Reference

Data Types

type  gwfnpftype
 
type  defaultflowformulationtype
 Default conductance flow formulation. More...
 

Functions/Subroutines

subroutine, public npf_cr (npfobj, name_model, input_mempath, inunit, iout)
 Create a new NPF object. Pass a inunit value of 0 if npf data will initialized from memory. More...
 
subroutine npf_df (this, dis, xt3d, ingnc, invsc, npf_options)
 Define the NPF package instance. More...
 
subroutine npf_ac (this, moffset, sparse)
 Add connections for extended neighbors to the sparse matrix. More...
 
subroutine npf_mc (this, moffset, matrix_sln)
 Map connections and construct iax, jax, and idxglox. More...
 
subroutine npf_ar (this, ic, vsc, ibound, hnew)
 Allocate and read this NPF instance. More...
 
subroutine npf_rp (this)
 Read and prepare method for package. More...
 
subroutine npf_ad (this, nodes, hold, hnew, irestore)
 Advance. More...
 
subroutine npf_cf (this, kiter, nodes, hnew)
 Calculate coefficients. More...
 
subroutine default_flow_cf (this, kiter)
 Calculate coefficients for the default conductance formulation. More...
 
subroutine cf_default_flow (this, kiter, n)
 Calculate coefficients using the. More...
 
subroutine npf_fc (this, kiter, matrix_sln, idxglo, rhs, hnew)
 Formulate coefficients. More...
 
subroutine fc_default_flow (this, n, m, ipos, matrix_sln, rhs, idxglo, hnew)
 Calculate and add coefficients using the. More...
 
subroutine default_flow_fc (this, kiter, matrix_sln, idxglo, rhs, hnew)
 Fill coefficients for the default conductance formulation. More...
 
subroutine highest_cell_saturation (this, n, m, hn, hm, satn, satm)
 Calculate dry cell saturation. More...
 
subroutine npf_fn (this, kiter, matrix_sln, idxglo, rhs, hnew)
 Fill newton terms. More...
 
subroutine default_flow_fn (this, kiter, matrix_sln, idxglo, rhs, hnew)
 Fill newton terms for the default conductance formulation. More...
 
subroutine fn_default_flow (this, n, m, ipos, matrix_sln, rhs, idxglo, hnew)
 
subroutine npf_nur (this, neqmod, x, xtemp, dx, inewtonur, dxmax, locmax)
 Under-relaxation. More...
 
subroutine npf_cq (this, hnew, flowja)
 Calculate flowja. More...
 
subroutine default_flow_cq (this, hnew, flowja)
 Calculate flows for the default conductance formulation. More...
 
subroutine cq_default_flow (this, n, m, ipos, flowja, hnew)
 
subroutine sgwf_npf_thksat (this, n, hn, thksat)
 Fractional cell saturation. More...
 
subroutine sgwf_npf_qcalc (this, n, m, hn, hm, icon, qnm)
 Flow between two cells. More...
 
subroutine npf_save_model_flows (this, flowja, icbcfl, icbcun)
 Record flowja and calculate specific discharge if requested. More...
 
subroutine npf_print_model_flows (this, ibudfl, flowja)
 Print budget. More...
 
subroutine npf_da (this)
 Deallocate variables. More...
 
subroutine allocate_scalars (this)
 @ brief Allocate scalars More...
 
subroutine store_original_k_arrays (this, ncells, njas)
 @ brief Store backup copy of hydraulic conductivity when the VSC package is activate More...
 
subroutine allocate_arrays (this, ncells, njas)
 Allocate npf arrays. More...
 
subroutine log_options (this, found)
 Log npf options sourced from the input mempath. More...
 
subroutine source_options (this)
 Update simulation options from input mempath. More...
 
subroutine set_options (this, options)
 Set options in the NPF object. More...
 
subroutine check_options (this)
 Check for conflicting NPF options. More...
 
subroutine log_griddata (this, found)
 Write dimensions to list file. More...
 
subroutine source_griddata (this)
 Update simulation griddata from input mempath. More...
 
subroutine prepcheck (this)
 Initialize and check NPF data. More...
 
subroutine preprocess_input (this)
 preprocess the NPF input data More...
 
subroutine calc_condsat (this, node, upperOnly)
 Calculate CONDSAT array entries for the given node. More...
 
real(dp) function calc_initial_sat (this, n)
 Calculate initial saturation for the given node. More...
 
subroutine sgwf_npf_wetdry (this, kiter, hnew)
 Perform wetting and drying. More...
 
subroutine rewet_check (this, kiter, node, hm, ibdm, ihc, hnew, irewet)
 Determine if a cell should rewet. More...
 
subroutine sgwf_npf_wdmsg (this, icode, ncnvrt, nodcnvrt, acnvrt, ihdcnv, kiter, n)
 Print wet/dry message. More...
 
real(dp) function hy_eff (this, n, m, ihc, ipos, vg)
 Calculate the effective hydraulic conductivity for the n-m connection. More...
 
subroutine calc_spdis (this, flowja)
 Calculate the 3 components of specific discharge at the cell center. More...
 
subroutine sav_spdis (this, ibinun)
 Save specific discharge in binary format to ibinun. More...
 
subroutine sav_sat (this, ibinun)
 Save saturation in binary format to ibinun. More...
 
subroutine increase_edge_count (this, nedges)
 Reserve space for nedges cells that have an edge on them. More...
 
integer(i4b) function calc_max_conns (this)
 Calculate the maximum number of connections for any cell. More...
 
subroutine set_edge_properties (this, nodedge, ihcedge, q, area, nx, ny, distance)
 Provide the npf package with edge properties. More...
 
subroutine prepare_edge_lookup (this)
 
real(dp) function calcsatthickness (this, n, m, ihc)
 Calculate saturated thickness between cell n and m. More...
 
subroutine add_flow_formulation (this, npf_form, form_id)
 

Function/Subroutine Documentation

◆ add_flow_formulation()

subroutine gwfnpfmodule::add_flow_formulation ( class(gwfnpftype), intent(inout)  this,
class(gwfnpfformulationtype), pointer  npf_form,
integer(i4b)  form_id 
)
private
Parameters
[in,out]thisthis NPF instance
npf_formthe extended flow calculator
form_idthe id for the flow formulation

Definition at line 3133 of file gwf-npf.f90.

3134  class(GwfNpfType), intent(inout) :: this !< this NPF instance
3135  class(GwfNpfFormulationType), pointer :: npf_form !< the extended flow calculator
3136  integer(I4B) :: form_id !< the id for the flow formulation
3137 
3138  this%flow_formulations(form_id)%form => npf_form
3139 

◆ allocate_arrays()

subroutine gwfnpfmodule::allocate_arrays ( class(gwfnpftype), target  this,
integer(i4b), intent(in)  ncells,
integer(i4b), intent(in)  njas 
)

Definition at line 1437 of file gwf-npf.f90.

1438  ! -- dummy
1439  class(GwfNpftype), target :: this
1440  integer(I4B), intent(in) :: ncells
1441  integer(I4B), intent(in) :: njas
1442  ! -- local
1443  integer(I4B) :: n
1444  !
1445  call mem_allocate(this%ithickstartflag, ncells, 'ITHICKSTARTFLAG', &
1446  this%memoryPath)
1447  call mem_allocate(this%icelltype, ncells, 'ICELLTYPE', this%memoryPath)
1448  call mem_allocate(this%k11, ncells, 'K11', this%memoryPath)
1449  call mem_allocate(this%krel, ncells, 'KREL', this%memoryPath)
1450  call mem_allocate(this%sat, ncells, 'SAT', this%memoryPath)
1451  call mem_allocate(this%condsat, njas, 'CONDSAT', this%memoryPath)
1452  !
1453  ! -- Optional arrays dimensioned to full size initially
1454  call mem_allocate(this%k22, ncells, 'K22', this%memoryPath)
1455  call mem_allocate(this%k33, ncells, 'K33', this%memoryPath)
1456  call mem_allocate(this%wetdry, ncells, 'WETDRY', this%memoryPath)
1457  call mem_allocate(this%angle1, ncells, 'ANGLE1', this%memoryPath)
1458  call mem_allocate(this%angle2, ncells, 'ANGLE2', this%memoryPath)
1459  call mem_allocate(this%angle3, ncells, 'ANGLE3', this%memoryPath)
1460  !
1461  ! -- Optional arrays
1462  call mem_allocate(this%ibotnode, 0, 'IBOTNODE', this%memoryPath)
1463  call mem_allocate(this%nodedge, 0, 'NODEDGE', this%memoryPath)
1464  call mem_allocate(this%ihcedge, 0, 'IHCEDGE', this%memoryPath)
1465  call mem_allocate(this%propsedge, 0, 0, 'PROPSEDGE', this%memoryPath)
1466  call mem_allocate(this%iedge_ptr, 0, 'NREDGESNODE', this%memoryPath)
1467  call mem_allocate(this%edge_idxs, 0, 'EDGEIDXS', this%memoryPath)
1468  !
1469  ! -- Optional arrays only needed when vsc package is active
1470  call mem_allocate(this%k11input, 0, 'K11INPUT', this%memoryPath)
1471  call mem_allocate(this%k22input, 0, 'K22INPUT', this%memoryPath)
1472  call mem_allocate(this%k33input, 0, 'K33INPUT', this%memoryPath)
1473  !
1474  ! -- Specific discharge is (re-)allocated when nedges is known
1475  call mem_allocate(this%spdis, 3, 0, 'SPDIS', this%memoryPath)
1476  !
1477  ! -- Time-varying property flag arrays
1478  call mem_allocate(this%nodekchange, ncells, 'NODEKCHANGE', this%memoryPath)
1479  !
1480  call mem_allocate(this%iformulation, this%dis%con%nja, 'IFORM', &
1481  this%memoryPath)
1482  !
1483  ! -- set to standard NPF flow
1484  do n = 1, size(this%iformulation)
1485  this%iformulation(n) = default_flow
1486  end do
1487  !
1488  ! -- create the default conductance formulation and point it at this package
1489  allocate (defaultflowformulationtype :: this%default_form)
1490  select type (form => this%default_form)
1491  type is (defaultflowformulationtype)
1492  form%npf => this
1493  end select
1494  !
1495  ! -- initialize iangle1, iangle2, iangle3, and wetdry
1496  do n = 1, ncells
1497  this%angle1(n) = dzero
1498  this%angle2(n) = dzero
1499  this%angle3(n) = dzero
1500  this%wetdry(n) = dzero
1501  this%nodekchange(n) = dzero
1502  this%krel(n) = done
1503  end do
1504  !
1505  ! -- allocate variable names
1506  allocate (this%aname(this%iname))
1507  this%aname = [' ICELLTYPE', ' K', &
1508  ' K33', ' K22', &
1509  ' WETDRY', ' ANGLE1', &
1510  ' ANGLE2', ' ANGLE3']

◆ allocate_scalars()

subroutine gwfnpfmodule::allocate_scalars ( class(gwfnpftype)  this)

Allocate and initialize scalars for the VSC package. The base model allocate scalars method is also called.

Definition at line 1318 of file gwf-npf.f90.

1319  ! -- modules
1321  ! -- dummy
1322  class(GwfNpftype) :: this
1323  !
1324  ! -- allocate scalars in NumericalPackageType
1325  call this%NumericalPackageType%allocate_scalars()
1326  !
1327  ! -- Allocate scalars
1328  call mem_allocate(this%iname, 'INAME', this%memoryPath)
1329  call mem_allocate(this%ixt3d, 'IXT3D', this%memoryPath)
1330  call mem_allocate(this%ixt3drhs, 'IXT3DRHS', this%memoryPath)
1331  call mem_allocate(this%satomega, 'SATOMEGA', this%memoryPath)
1332  call mem_allocate(this%hnoflo, 'HNOFLO', this%memoryPath)
1333  call mem_allocate(this%hdry, 'HDRY', this%memoryPath)
1334  call mem_allocate(this%icellavg, 'ICELLAVG', this%memoryPath)
1335  call mem_allocate(this%iavgkeff, 'IAVGKEFF', this%memoryPath)
1336  call mem_allocate(this%ik22, 'IK22', this%memoryPath)
1337  call mem_allocate(this%ik33, 'IK33', this%memoryPath)
1338  call mem_allocate(this%ik22overk, 'IK22OVERK', this%memoryPath)
1339  call mem_allocate(this%ik33overk, 'IK33OVERK', this%memoryPath)
1340  call mem_allocate(this%iperched, 'IPERCHED', this%memoryPath)
1341  call mem_allocate(this%ivarcv, 'IVARCV', this%memoryPath)
1342  call mem_allocate(this%idewatcv, 'IDEWATCV', this%memoryPath)
1343  call mem_allocate(this%ithickstrt, 'ITHICKSTRT', this%memoryPath)
1344  call mem_allocate(this%ihighcellsat, 'IHIGHCELLSAT', this%memoryPath)
1345  call mem_allocate(this%icalcspdis, 'ICALCSPDIS', this%memoryPath)
1346  call mem_allocate(this%isavspdis, 'ISAVSPDIS', this%memoryPath)
1347  call mem_allocate(this%isavsat, 'ISAVSAT', this%memoryPath)
1348  call mem_allocate(this%irewet, 'IREWET', this%memoryPath)
1349  call mem_allocate(this%wetfct, 'WETFCT', this%memoryPath)
1350  call mem_allocate(this%iwetit, 'IWETIT', this%memoryPath)
1351  call mem_allocate(this%ihdwet, 'IHDWET', this%memoryPath)
1352  call mem_allocate(this%iangle1, 'IANGLE1', this%memoryPath)
1353  call mem_allocate(this%iangle2, 'IANGLE2', this%memoryPath)
1354  call mem_allocate(this%iangle3, 'IANGLE3', this%memoryPath)
1355  call mem_allocate(this%iwetdry, 'IWETDRY', this%memoryPath)
1356  call mem_allocate(this%nedges, 'NEDGES', this%memoryPath)
1357  call mem_allocate(this%lastedge, 'LASTEDGE', this%memoryPath)
1358  call mem_allocate(this%intvk, 'INTVK', this%memoryPath)
1359  call mem_allocate(this%invsc, 'INVSC', this%memoryPath)
1360  call mem_allocate(this%kchangeper, 'KCHANGEPER', this%memoryPath)
1361  call mem_allocate(this%kchangestp, 'KCHANGESTP', this%memoryPath)
1362  !
1363  ! -- set pointer to inewtonur
1364  call mem_setptr(this%igwfnewtonur, 'INEWTONUR', &
1365  create_mem_path(this%name_model))
1366  !
1367  ! -- Initialize value
1368  this%iname = 8
1369  this%ixt3d = 0
1370  this%ixt3drhs = 0
1371  this%satomega = dzero
1372  this%hnoflo = dhnoflo !1.d30
1373  this%hdry = dhdry !-1.d30
1374  this%icellavg = ccond_hmean
1375  this%iavgkeff = 0
1376  this%ik22 = 0
1377  this%ik33 = 0
1378  this%ik22overk = 0
1379  this%ik33overk = 0
1380  this%iperched = 0
1381  this%ivarcv = 0
1382  this%idewatcv = 0
1383  this%ithickstrt = 0
1384  this%ihighcellsat = 0
1385  this%icalcspdis = 0
1386  this%isavspdis = 0
1387  this%isavsat = 0
1388  this%irewet = 0
1389  this%wetfct = done
1390  this%iwetit = 1
1391  this%ihdwet = 0
1392  this%iangle1 = 0
1393  this%iangle2 = 0
1394  this%iangle3 = 0
1395  this%iwetdry = 0
1396  this%nedges = 0
1397  this%lastedge = 0
1398  this%intvk = 0
1399  this%invsc = 0
1400  this%kchangeper = 0
1401  this%kchangestp = 0
1402  !
1403  ! -- If newton is on, then NPF creates asymmetric matrix
1404  this%iasym = this%inewton
character(len=lenmempath) function create_mem_path(component, subcomponent, context)
returns the path to the memory object
Here is the call graph for this function:

◆ calc_condsat()

subroutine gwfnpfmodule::calc_condsat ( class(gwfnpftype)  this,
integer(i4b), intent(in)  node,
logical, intent(in)  upperOnly 
)

Calculate saturated conductances for all connections of the given node, or optionally for the upper portion of the matrix only.

Definition at line 2277 of file gwf-npf.f90.

2278  ! -- dummy variables
2279  class(GwfNpfType) :: this
2280  integer(I4B), intent(in) :: node
2281  logical, intent(in) :: upperOnly
2282  ! -- local variables
2283  integer(I4B) :: ii, m, n, ihc, jj
2284  real(DP) :: topm, topn, topnode, botm, botn, botnode, satm, satn, satnode
2285  real(DP) :: hyn, hym, hn, hm, fawidth, csat
2286  !
2287  satnode = this%calc_initial_sat(node)
2288  !
2289  topnode = this%dis%top(node)
2290  botnode = this%dis%bot(node)
2291  !
2292  ! -- Go through the connecting cells
2293  do ii = this%dis%con%ia(node) + 1, this%dis%con%ia(node + 1) - 1
2294  !
2295  ! -- Set the m cell number and cycle if lower triangle connection and
2296  ! -- we're not updating both upper and lower matrix parts for this node
2297  m = this%dis%con%ja(ii)
2298  jj = this%dis%con%jas(ii)
2299  if (m < node) then
2300  if (upperonly) cycle
2301  ! m => node, n => neighbour
2302  n = m
2303  m = node
2304  topm = topnode
2305  botm = botnode
2306  satm = satnode
2307  topn = this%dis%top(n)
2308  botn = this%dis%bot(n)
2309  satn = this%calc_initial_sat(n)
2310  else
2311  ! n => node, m => neighbour
2312  n = node
2313  topn = topnode
2314  botn = botnode
2315  satn = satnode
2316  topm = this%dis%top(m)
2317  botm = this%dis%bot(m)
2318  satm = this%calc_initial_sat(m)
2319  end if
2320  !
2321  ihc = this%dis%con%ihc(jj)
2322  hyn = this%hy_eff(n, m, ihc, ipos=ii)
2323  hym = this%hy_eff(m, n, ihc, ipos=ii)
2324  if (this%ithickstartflag(n) == 0) then
2325  hn = topn
2326  else
2327  hn = this%ic%strt(n)
2328  end if
2329  if (this%ithickstartflag(m) == 0) then
2330  hm = topm
2331  else
2332  hm = this%ic%strt(m)
2333  end if
2334  !
2335  ! -- Calculate conductance depending on whether connection is
2336  ! vertical (0), horizontal (1), or staggered horizontal (2)
2337  if (ihc == c3d_vertical) then
2338  !
2339  ! -- Vertical conductance for fully saturated conditions
2340  csat = vcond(1, 1, 1, 1, 0, 1, 1, done, &
2341  botn, botm, &
2342  hyn, hym, &
2343  satn, satm, &
2344  topn, topm, &
2345  botn, botm, &
2346  this%dis%con%hwva(jj))
2347  else
2348  !
2349  ! -- Horizontal conductance for fully saturated conditions
2350  fawidth = this%dis%con%hwva(jj)
2351  csat = hcond(1, 1, 1, 1, 0, &
2352  ihc, &
2353  this%icellavg, &
2354  done, &
2355  hn, hm, satn, satm, hyn, hym, &
2356  topn, topm, &
2357  botn, botm, &
2358  this%dis%con%cl1(jj), &
2359  this%dis%con%cl2(jj), &
2360  fawidth)
2361  end if
2362  this%condsat(jj) = csat
2363  end do
Here is the call graph for this function:

◆ calc_initial_sat()

real(dp) function gwfnpfmodule::calc_initial_sat ( class(gwfnpftype)  this,
integer(i4b), intent(in)  n 
)
private

Calculate saturation as a fraction of thickness for the given node, used for saturated conductance calculations: full thickness by default (1.0) or saturation based on initial conditions if the THICKSTRT option is used.

Definition at line 2373 of file gwf-npf.f90.

2374  ! -- dummy variables
2375  class(GwfNpfType) :: this
2376  integer(I4B), intent(in) :: n
2377  ! -- Return
2378  real(DP) :: satn
2379  !
2380  satn = done
2381  if (this%ibound(n) /= 0 .and. this%ithickstartflag(n) /= 0) then
2382  call this%thksat(n, this%ic%strt(n), satn)
2383  end if

◆ calc_max_conns()

integer(i4b) function gwfnpfmodule::calc_max_conns ( class(gwfnpftype)  this)
private

Definition at line 3007 of file gwf-npf.f90.

3008  class(GwfNpfType) :: this
3009  integer(I4B) :: max_conns
3010  ! local
3011  integer(I4B) :: n, m, ic
3012 
3013  max_conns = 0
3014  do n = 1, this%dis%nodes
3015 
3016  ! Count internal model connections
3017  ic = this%dis%con%ia(n + 1) - this%dis%con%ia(n) - 1
3018 
3019  ! Add edge connections
3020  do m = 1, this%nedges
3021  if (this%nodedge(m) == n) then
3022  ic = ic + 1
3023  end if
3024  end do
3025 
3026  ! Set max number of connections for any cell
3027  if (ic > max_conns) max_conns = ic
3028  end do
3029 

◆ calc_spdis()

subroutine gwfnpfmodule::calc_spdis ( class(gwfnpftype)  this,
real(dp), dimension(:), intent(in)  flowja 
)
private

Definition at line 2686 of file gwf-npf.f90.

2687  ! -- modules
2688  use simmodule, only: store_error
2689  ! -- dummy
2690  class(GwfNpfType) :: this
2691  real(DP), intent(in), dimension(:) :: flowja
2692  ! -- local
2693  integer(I4B) :: n
2694  integer(I4B) :: m
2695  integer(I4B) :: ipos
2696  integer(I4B) :: iedge
2697  integer(I4B) :: isympos
2698  integer(I4B) :: ihc
2699  integer(I4B) :: ic
2700  integer(I4B) :: iz
2701  integer(I4B) :: nc
2702  integer(I4B) :: ncz
2703  real(DP) :: qz
2704  real(DP) :: vx
2705  real(DP) :: vy
2706  real(DP) :: vz
2707  real(DP) :: xn
2708  real(DP) :: yn
2709  real(DP) :: zn
2710  real(DP) :: xc
2711  real(DP) :: yc
2712  real(DP) :: zc
2713  real(DP) :: cl1
2714  real(DP) :: cl2
2715  real(DP) :: dltot
2716  real(DP) :: ooclsum
2717  real(DP) :: dsumx
2718  real(DP) :: dsumy
2719  real(DP) :: dsumz
2720  real(DP) :: denom
2721  real(DP) :: area
2722  real(DP) :: dz
2723  real(DP) :: axy
2724  real(DP) :: ayx
2725  logical :: nozee = .true.
2726  type(SpdisWorkArrayType), pointer :: swa => null() !< pointer to spdis work arrays structure
2727  !
2728  ! -- Ensure dis has necessary information
2729  if (this%icalcspdis /= 0 .and. this%dis%con%ianglex == 0) then
2730  call store_error('Error. ANGLDEGX not provided in '// &
2731  'discretization file. ANGLDEGX required for '// &
2732  'calculation of specific discharge.', terminate=.true.)
2733  end if
2734 
2735  swa => this%spdis_wa
2736  if (.not. swa%is_created()) then
2737  ! prepare work arrays
2738  call this%spdis_wa%create(this%calc_max_conns())
2739 
2740  ! prepare lookup table
2741  if (this%nedges > 0) call this%prepare_edge_lookup()
2742  end if
2743  !
2744  ! -- Go through each cell and calculate specific discharge
2745  do n = 1, this%dis%nodes
2746  !
2747  ! -- first calculate geometric properties for x and y directions and
2748  ! the specific discharge at a face (vi)
2749  ic = 0
2750  iz = 0
2751 
2752  ! reset work arrays
2753  call swa%reset()
2754 
2755  do ipos = this%dis%con%ia(n) + 1, this%dis%con%ia(n + 1) - 1
2756  m = this%dis%con%ja(ipos)
2757  isympos = this%dis%con%jas(ipos)
2758  ihc = this%dis%con%ihc(isympos)
2759  area = this%dis%con%hwva(isympos)
2760  if (ihc == c3d_vertical) then
2761  !
2762  ! -- vertical connection
2763  iz = iz + 1
2764  !call this%dis%connection_normal(n, m, ihc, xn, yn, zn, ipos)
2765  call this%dis%connection_vector(n, m, nozee, this%sat(n), this%sat(m), &
2766  ihc, xc, yc, zc, dltot)
2767  cl1 = this%dis%con%cl1(isympos)
2768  cl2 = this%dis%con%cl2(isympos)
2769  if (m < n) then
2770  cl1 = this%dis%con%cl2(isympos)
2771  cl2 = this%dis%con%cl1(isympos)
2772  end if
2773  ooclsum = done / (cl1 + cl2)
2774  swa%diz(iz) = dltot * cl1 * ooclsum
2775  qz = flowja(ipos)
2776  if (n > m) qz = -qz
2777  swa%viz(iz) = qz / area
2778  else
2779  !
2780  ! -- horizontal connection
2781  ic = ic + 1
2782  dz = thksatnm(this%ibound(n), this%ibound(m), &
2783  this%icelltype(n), this%icelltype(m), &
2784  this%inewton, ihc, &
2785  this%hnew(n), this%hnew(m), this%sat(n), this%sat(m), &
2786  this%dis%top(n), this%dis%top(m), this%dis%bot(n), &
2787  this%dis%bot(m))
2788  area = area * dz
2789  call this%dis%connection_normal(n, m, ihc, xn, yn, zn, ipos)
2790  call this%dis%connection_vector(n, m, nozee, this%sat(n), this%sat(m), &
2791  ihc, xc, yc, zc, dltot)
2792  cl1 = this%dis%con%cl1(isympos)
2793  cl2 = this%dis%con%cl2(isympos)
2794  if (m < n) then
2795  cl1 = this%dis%con%cl2(isympos)
2796  cl2 = this%dis%con%cl1(isympos)
2797  end if
2798  ooclsum = done / (cl1 + cl2)
2799  swa%nix(ic) = -xn
2800  swa%niy(ic) = -yn
2801  swa%di(ic) = dltot * cl1 * ooclsum
2802  if (area > dzero) then
2803  swa%vi(ic) = flowja(ipos) / area
2804  else
2805  swa%vi(ic) = dzero
2806  end if
2807  end if
2808  end do
2809 
2810  ! add contribution from edge flows (i.e. from exchanges)
2811  if (this%nedges > 0) then
2812  do ipos = this%iedge_ptr(n), this%iedge_ptr(n + 1) - 1
2813  iedge = this%edge_idxs(ipos)
2814 
2815  ! propsedge: (Q, area, nx, ny, distance)
2816  ihc = this%ihcedge(iedge)
2817  area = this%propsedge(2, iedge)
2818  if (ihc == c3d_vertical) then
2819  iz = iz + 1
2820  swa%viz(iz) = this%propsedge(1, iedge) / area
2821  swa%diz(iz) = this%propsedge(5, iedge)
2822  else
2823  ic = ic + 1
2824  swa%nix(ic) = -this%propsedge(3, iedge)
2825  swa%niy(ic) = -this%propsedge(4, iedge)
2826  swa%di(ic) = this%propsedge(5, iedge)
2827  if (area > dzero) then
2828  swa%vi(ic) = this%propsedge(1, iedge) / area
2829  else
2830  swa%vi(ic) = dzero
2831  end if
2832  end if
2833  end do
2834  end if
2835  !
2836  ! -- Assign number of vertical and horizontal connections
2837  ncz = iz
2838  nc = ic
2839  !
2840  ! -- calculate z weight (wiz) and z velocity
2841  if (ncz == 1) then
2842  swa%wiz(1) = done
2843  else
2844  dsumz = dzero
2845  do iz = 1, ncz
2846  dsumz = dsumz + swa%diz(iz)
2847  end do
2848  denom = (ncz - done)
2849  if (denom < dzero) denom = dzero
2850  dsumz = dsumz + dem10 * dsumz
2851  do iz = 1, ncz
2852  if (dsumz > dzero) swa%wiz(iz) = done - swa%diz(iz) / dsumz
2853  if (denom > 0) then
2854  swa%wiz(iz) = swa%wiz(iz) / denom
2855  else
2856  swa%wiz(iz) = dzero
2857  end if
2858  end do
2859  end if
2860  vz = dzero
2861  do iz = 1, ncz
2862  vz = vz + swa%wiz(iz) * swa%viz(iz)
2863  end do
2864  !
2865  ! -- distance-based weighting
2866  nc = ic
2867  dsumx = dzero
2868  dsumy = dzero
2869  dsumz = dzero
2870  do ic = 1, nc
2871  swa%wix(ic) = swa%di(ic) * abs(swa%nix(ic))
2872  swa%wiy(ic) = swa%di(ic) * abs(swa%niy(ic))
2873  dsumx = dsumx + swa%wix(ic)
2874  dsumy = dsumy + swa%wiy(ic)
2875  end do
2876  !
2877  ! -- Finish computing omega weights. Add a tiny bit
2878  ! to dsum so that the normalized omega weight later
2879  ! evaluates to (essentially) 1 in the case of a single
2880  ! relevant connection, avoiding 0/0.
2881  dsumx = dsumx + dem10 * dsumx
2882  dsumy = dsumy + dem10 * dsumy
2883  do ic = 1, nc
2884  swa%wix(ic) = (dsumx - swa%wix(ic)) * abs(swa%nix(ic))
2885  swa%wiy(ic) = (dsumy - swa%wiy(ic)) * abs(swa%niy(ic))
2886  end do
2887  !
2888  ! -- compute B weights
2889  dsumx = dzero
2890  dsumy = dzero
2891  do ic = 1, nc
2892  swa%bix(ic) = swa%wix(ic) * sign(done, swa%nix(ic))
2893  swa%biy(ic) = swa%wiy(ic) * sign(done, swa%niy(ic))
2894  dsumx = dsumx + swa%wix(ic) * abs(swa%nix(ic))
2895  dsumy = dsumy + swa%wiy(ic) * abs(swa%niy(ic))
2896  end do
2897  if (dsumx > dzero) dsumx = done / dsumx
2898  if (dsumy > dzero) dsumy = done / dsumy
2899  axy = dzero
2900  ayx = dzero
2901  do ic = 1, nc
2902  swa%bix(ic) = swa%bix(ic) * dsumx
2903  swa%biy(ic) = swa%biy(ic) * dsumy
2904  axy = axy + swa%bix(ic) * swa%niy(ic)
2905  ayx = ayx + swa%biy(ic) * swa%nix(ic)
2906  end do
2907  !
2908  ! -- Calculate specific discharge. The divide by zero checking below
2909  ! is problematic for cells with only one flow, such as can happen
2910  ! with triangular cells in corners. In this case, the resulting
2911  ! cell velocity will be calculated as zero. The method should be
2912  ! improved so that edge flows of zero are included in these
2913  ! calculations. But this needs to be done with consideration for LGR
2914  ! cases in which flows are submitted from an exchange.
2915  vx = dzero
2916  vy = dzero
2917  do ic = 1, nc
2918  vx = vx + (swa%bix(ic) - axy * swa%biy(ic)) * swa%vi(ic)
2919  vy = vy + (swa%biy(ic) - ayx * swa%bix(ic)) * swa%vi(ic)
2920  end do
2921  denom = done - axy * ayx
2922  if (denom /= dzero) then
2923  vx = vx / denom
2924  vy = vy / denom
2925  end if
2926  !
2927  this%spdis(1, n) = vx
2928  this%spdis(2, n) = vy
2929  this%spdis(3, n) = vz
2930  !
2931  end do
2932 
This module contains simulation methods.
Definition: Sim.f90:10
subroutine, public store_error(msg, terminate)
Store an error message.
Definition: Sim.f90:92
Here is the call graph for this function:

◆ calcsatthickness()

real(dp) function gwfnpfmodule::calcsatthickness ( class(gwfnpftype)  this,
integer(i4b)  n,
integer(i4b)  m,
integer(i4b)  ihc 
)
private
Parameters
thisthis NPF instance
nnode n
mnode m
ihc1 = horizontal connection, 0 for vertical
Returns
saturated thickness

Definition at line 3108 of file gwf-npf.f90.

3109  ! -- dummy
3110  class(GwfNpfType) :: this !< this NPF instance
3111  integer(I4B) :: n !< node n
3112  integer(I4B) :: m !< node m
3113  integer(I4B) :: ihc !< 1 = horizontal connection, 0 for vertical
3114  ! -- return
3115  real(DP) :: satThickness !< saturated thickness
3116  !
3117  satthickness = thksatnm(this%ibound(n), &
3118  this%ibound(m), &
3119  this%icelltype(n), &
3120  this%icelltype(m), &
3121  this%inewton, &
3122  ihc, &
3123  this%hnew(n), &
3124  this%hnew(m), &
3125  this%sat(n), &
3126  this%sat(m), &
3127  this%dis%top(n), &
3128  this%dis%top(m), &
3129  this%dis%bot(n), &
3130  this%dis%bot(m))

◆ cf_default_flow()

subroutine gwfnpfmodule::cf_default_flow ( class(gwfnpftype)  this,
integer(i4b)  kiter,
integer(i4b)  n 
)
private

Definition at line 540 of file gwf-npf.f90.

541  class(GwfNpfType) :: this
542  integer(I4B) :: kiter
543  integer(I4B) :: n
544  ! local
545  real(DP) :: satn
546 
547  ! Calculate saturated fraction for convertible cells
548  if (this%icelltype(n) /= 0) then
549  if (this%ibound(n) == 0) then
550  satn = dzero
551  else
552  call this%thksat(n, this%hnew(n), satn)
553  end if
554  this%sat(n) = satn
555  end if
556 

◆ check_options()

subroutine gwfnpfmodule::check_options ( class(gwfnpftype)  this)
private

Definition at line 1698 of file gwf-npf.f90.

1699  ! -- modules
1700  use simmodule, only: store_error, store_warning, &
1702  use constantsmodule, only: linelength
1703  ! -- dummy
1704  class(GwfNpftype) :: this
1705  !
1706  ! -- set omega value used for saturation calculations
1707  if (this%inewton > 0) then
1708  this%satomega = dem6
1709  end if
1710  !
1711  if (this%inewton > 0) then
1712  if (this%iperched > 0) then
1713  write (errmsg, '(a)') 'ERROR IN NPF OPTIONS. NEWTON OPTION CANNOT '// &
1714  'BE USED WITH PERCHED OPTION.'
1715  call store_error(errmsg)
1716  end if
1717  if (this%ivarcv > 0) then
1718  write (errmsg, '(a)') 'ERROR IN NPF OPTIONS. NEWTON OPTION CANNOT '// &
1719  'BE USED WITH VARIABLECV OPTION.'
1720  call store_error(errmsg)
1721  end if
1722  if (this%irewet > 0) then
1723  write (errmsg, '(a)') 'ERROR IN NPF OPTIONS. NEWTON OPTION CANNOT '// &
1724  'BE USED WITH REWET OPTION.'
1725  call store_error(errmsg)
1726  end if
1727  else
1728  if (this%ihighcellsat /= 0) then
1729  write (warnmsg, '(a)') 'HIGHEST_CELL_SATURATION '// &
1730  'option cannot be used when NEWTON option in not specified. '// &
1731  'Resetting HIGHEST_CELL_SATURATION option to off.'
1732  this%ihighcellsat = 0
1733  call store_warning(warnmsg)
1734  end if
1735  end if
1736  !
1737  if (this%ixt3d /= 0) then
1738  if (this%icellavg > 0) then
1739  write (errmsg, '(a)') 'ERROR IN NPF OPTIONS. '// &
1740  'ALTERNATIVE_CELL_AVERAGING OPTION '// &
1741  'CANNOT BE USED WITH XT3D OPTION.'
1742  call store_error(errmsg)
1743  end if
1744  if (this%ithickstrt > 0) then
1745  write (errmsg, '(a)') 'ERROR IN NPF OPTIONS. THICKSTRT OPTION '// &
1746  'CANNOT BE USED WITH XT3D OPTION.'
1747  call store_error(errmsg)
1748  end if
1749  if (this%iperched > 0) then
1750  write (errmsg, '(a)') 'ERROR IN NPF OPTIONS. PERCHED OPTION '// &
1751  'CANNOT BE USED WITH XT3D OPTION.'
1752  call store_error(errmsg)
1753  end if
1754  if (this%ivarcv > 0) then
1755  write (errmsg, '(a)') 'ERROR IN NPF OPTIONS. VARIABLECV OPTION '// &
1756  'CANNOT BE USED WITH XT3D OPTION.'
1757  call store_error(errmsg)
1758  end if
1759  end if
1760  !
1761  ! -- Terminate if errors
1762  if (count_errors() > 0) then
1763  call store_error_filename(this%input_fname)
1764  end if
This module contains simulation constants.
Definition: Constants.f90:9
integer(i4b), parameter linelength
maximum length of a standard line
Definition: Constants.f90:45
subroutine, public store_warning(msg, substring)
Store warning message.
Definition: Sim.f90:237
integer(i4b) function, public count_errors()
Return number of errors.
Definition: Sim.f90:59
subroutine, public store_error_filename(filename, terminate)
Store the erroring file name.
Definition: Sim.f90:204
Here is the call graph for this function:

◆ cq_default_flow()

subroutine gwfnpfmodule::cq_default_flow ( class(gwfnpftype)  this,
integer(i4b), intent(in)  n,
integer(i4b), intent(in)  m,
integer(i4b), intent(in)  ipos,
real(dp), dimension(:), intent(inout)  flowja,
real(dp), dimension(:), intent(in)  hnew 
)
private

Definition at line 1015 of file gwf-npf.f90.

1016  class(GwfNpfType) :: this
1017  integer(I4B), intent(in) :: n
1018  integer(I4B), intent(in) :: m
1019  integer(I4B), intent(in) :: ipos
1020  real(DP), dimension(:), intent(inout) :: flowja
1021  real(DP), dimension(:), intent(in) :: hnew
1022  ! local
1023  real(DP) :: qnm
1024 
1025  call this%qcalc(n, m, hnew(n), hnew(m), ipos, qnm)
1026  flowja(ipos) = qnm
1027  flowja(this%dis%con%isym(ipos)) = -qnm
1028 

◆ default_flow_cf()

subroutine gwfnpfmodule::default_flow_cf ( class(defaultflowformulationtype), intent(inout)  this,
integer(i4b), intent(in)  kiter 
)
private

Runs over all cells and computes the saturated fraction for convertible cells, skipping cells claimed by an exclusive formulation.

Parameters
[in,out]thisdefault formulation
[in]kiterouter iteration number

Definition at line 523 of file gwf-npf.f90.

524  class(DefaultFlowFormulationType), intent(inout) :: this !< default formulation
525  integer(I4B), intent(in) :: kiter !< outer iteration number
526  ! local
527  integer(I4B) :: n, idiag
528 
529  do n = 1, this%npf%dis%nodes
530  ! skip cells claimed by an exclusive formulation
531  idiag = this%npf%dis%con%ia(n)
532  if (this%npf%iformulation(idiag) /= default_flow) cycle
533  call this%npf%cf_default_flow(kiter, n)
534  end do
535 

◆ default_flow_cq()

subroutine gwfnpfmodule::default_flow_cq ( class(defaultflowformulationtype), intent(inout)  this,
real(dp), dimension(:), intent(inout)  hnew,
real(dp), dimension(:), intent(inout)  flowja 
)
private

Runs over all connections and stores the standard NPF face flows, skipping faces claimed by an exclusive formulation.

Parameters
[in,out]thisdefault formulation
[in,out]hnewnew head values
[in,out]flowjaflow between cells

Definition at line 993 of file gwf-npf.f90.

994  class(DefaultFlowFormulationType), intent(inout) :: this !< default formulation
995  real(DP), dimension(:), intent(inout) :: hnew !< new head values
996  real(DP), dimension(:), intent(inout) :: flowja !< flow between cells
997  ! local
998  integer(I4B) :: n, m, ipos
999 
1000  do n = 1, this%npf%dis%nodes
1001  do ipos = this%npf%dis%con%ia(n) + 1, this%npf%dis%con%ia(n + 1) - 1
1002  m = this%npf%dis%con%ja(ipos)
1003  if (m < n) cycle
1004  !TODO_MJR: why don't we exclude masked connections here?
1005 
1006  ! skip faces claimed by an exclusive formulation
1007  if (this%npf%iformulation(ipos) /= default_flow) cycle
1008 
1009  call this%npf%cq_default_flow(n, m, ipos, flowja, hnew)
1010  end do
1011  end do
1012 

◆ default_flow_fc()

subroutine gwfnpfmodule::default_flow_fc ( class(defaultflowformulationtype), intent(inout)  this,
integer(i4b), intent(in)  kiter,
class(matrixbasetype), intent(inout), pointer  matrix_sln,
integer(i4b), dimension(:), intent(in)  idxglo,
real(dp), dimension(:), intent(inout)  rhs,
real(dp), dimension(:), intent(inout)  hnew 
)
private

Runs over all connections and fills the standard NPF conductance terms, skipping faces claimed by an exclusive formulation.

Parameters
[in,out]thisdefault formulation
[in]kiterouter iteration number
[in,out]matrix_slnsystem matrix
[in]idxglolocal to global connection map
[in,out]rhsright-hand side vector
[in,out]hnewnew head values

Definition at line 683 of file gwf-npf.f90.

684  class(DefaultFlowFormulationType), intent(inout) :: this !< default formulation
685  integer(I4B), intent(in) :: kiter !< outer iteration number
686  class(MatrixBaseType), pointer, intent(inout) :: matrix_sln !< system matrix
687  integer(I4B), dimension(:), intent(in) :: idxglo !< local to global connection map
688  real(DP), dimension(:), intent(inout) :: rhs !< right-hand side vector
689  real(DP), dimension(:), intent(inout) :: hnew !< new head values
690  ! local
691  integer(I4B) :: n, m, ipos
692 
693  do n = 1, this%npf%dis%nodes
694  do ipos = this%npf%dis%con%ia(n) + 1, this%npf%dis%con%ia(n + 1) - 1
695  if (this%npf%dis%con%mask(ipos) == 0) cycle
696 
697  m = this%npf%dis%con%ja(ipos)
698 
699  ! Calculate upper triangle only, but insert into
700  ! upper and lower parts of matrix
701  if (m < n) cycle
702 
703  ! skip faces claimed by an exclusive formulation
704  if (this%npf%iformulation(ipos) /= default_flow) cycle
705 
706  call this%npf%fc_default_flow(n, m, ipos, matrix_sln, &
707  rhs, idxglo, hnew)
708  end do
709  end do
710 

◆ default_flow_fn()

subroutine gwfnpfmodule::default_flow_fn ( class(defaultflowformulationtype), intent(inout)  this,
integer(i4b), intent(in)  kiter,
class(matrixbasetype), intent(inout), pointer  matrix_sln,
integer(i4b), dimension(:), intent(in)  idxglo,
real(dp), dimension(:), intent(inout)  rhs,
real(dp), dimension(:), intent(inout)  hnew 
)
private

Runs over all connections and fills the standard NPF newton terms, skipping faces claimed by an exclusive formulation.

Parameters
[in,out]thisdefault formulation
[in]kiterouter iteration number
[in,out]matrix_slnsystem matrix
[in]idxglolocal to global connection map
[in,out]rhsright-hand side vector
[in,out]hnewnew head values

Definition at line 782 of file gwf-npf.f90.

783  class(DefaultFlowFormulationType), intent(inout) :: this !< default formulation
784  integer(I4B), intent(in) :: kiter !< outer iteration number
785  class(MatrixBaseType), pointer, intent(inout) :: matrix_sln !< system matrix
786  integer(I4B), dimension(:), intent(in) :: idxglo !< local to global connection map
787  real(DP), dimension(:), intent(inout) :: rhs !< right-hand side vector
788  real(DP), dimension(:), intent(inout) :: hnew !< new head values
789  ! local
790  integer(I4B) :: n, m, ipos
791 
792  do n = 1, this%npf%dis%nodes
793  do ipos = this%npf%dis%con%ia(n) + 1, this%npf%dis%con%ia(n + 1) - 1
794  if (this%npf%dis%con%mask(ipos) == 0) cycle
795 
796  m = this%npf%dis%con%ja(ipos)
797 
798  ! work on upper triangle
799  if (m < n) cycle
800 
801  ! skip faces claimed by an exclusive formulation
802  if (this%npf%iformulation(ipos) /= default_flow) cycle
803 
804  call this%npf%fn_default_flow(n, m, ipos, matrix_sln, &
805  rhs, idxglo, hnew)
806  end do
807  end do
808 

◆ fc_default_flow()

subroutine gwfnpfmodule::fc_default_flow ( class(gwfnpftype)  this,
integer(i4b)  n,
integer(i4b)  m,
integer(i4b)  ipos,
class(matrixbasetype), pointer  matrix_sln,
real(dp), dimension(:), intent(inout)  rhs,
integer(i4b), dimension(:), intent(in)  idxglo,
real(dp), dimension(:), intent(inout)  hnew 
)
private
Parameters
thisthis instance
nnode number n
mnode number m
iposconnection number
matrix_slnsystem matrix
[in,out]rhsrhs vector
[in]idxglolookup table from local ipos to global system
[in,out]hnewnew head values

Definition at line 589 of file gwf-npf.f90.

590  class(GwfNpfType) :: this !< this instance
591  integer(I4B) :: n !< node number n
592  integer(I4B) :: m !< node number m
593  integer(I4B) :: ipos !< connection number
594  class(MatrixBaseType), pointer :: matrix_sln !< system matrix
595  real(DP), intent(inout), dimension(:) :: rhs !< rhs vector
596  integer(I4B), intent(in), dimension(:) :: idxglo !< lookup table from local ipos to global system
597  real(DP), intent(inout), dimension(:) :: hnew !< new head values
598  ! local
599  integer(I4B) :: idiag, ihc
600  integer(I4B) :: isymcon, idiagm
601  real(DP) :: hyn, hym
602  real(DP) :: cond
603  real(DP) :: satn
604  real(DP) :: satm
605 
606  ihc = this%dis%con%ihc(this%dis%con%jas(ipos))
607  hyn = this%hy_eff(n, m, ihc, ipos=ipos)
608  hym = this%hy_eff(m, n, ihc, ipos=ipos)
609 
610  if (ihc == c3d_vertical) then
611  ! Horizontal conductance
612  cond = vcond(this%ibound(n), this%ibound(m), &
613  this%icelltype(n), this%icelltype(m), this%inewton, &
614  this%ivarcv, this%idewatcv, &
615  this%condsat(this%dis%con%jas(ipos)), hnew(n), hnew(m), &
616  hyn, hym, &
617  this%sat(n), this%sat(m), &
618  this%dis%top(n), this%dis%top(m), &
619  this%dis%bot(n), this%dis%bot(m), &
620  this%dis%con%hwva(this%dis%con%jas(ipos)))
621 
622  ! Vertical flow for perched conditions
623  if (this%iperched /= 0) then
624  if (this%icelltype(m) /= 0) then
625  if (hnew(m) < this%dis%top(m)) then
626 
627  ! Fill diagonal for n, and add to RHS
628  idiag = this%dis%con%ia(n)
629  rhs(n) = rhs(n) - cond * this%dis%bot(n)
630  call matrix_sln%add_value_pos(idxglo(idiag), -cond)
631 
632  ! Fill diagonal for m, and add to RHS
633  isymcon = this%dis%con%isym(ipos)
634  call matrix_sln%add_value_pos(idxglo(isymcon), cond)
635  rhs(m) = rhs(m) + cond * this%dis%bot(n)
636 
637  ! go to next connection
638  return
639  end if
640  end if
641  end if
642  else
643  satn = this%sat(n)
644  satm = this%sat(m)
645  if (this%ihighcellsat /= 0) then
646  call this%highest_cell_saturation(n, m, &
647  hnew(n), hnew(m), &
648  satn, satm)
649  end if
650  ! Horizontal conductance
651  cond = hcond(this%ibound(n), this%ibound(m), &
652  this%icelltype(n), this%icelltype(m), &
653  this%inewton, &
654  this%dis%con%ihc(this%dis%con%jas(ipos)), &
655  this%icellavg, &
656  this%condsat(this%dis%con%jas(ipos)), &
657  hnew(n), hnew(m), satn, satm, hyn, hym, &
658  this%dis%top(n), this%dis%top(m), &
659  this%dis%bot(n), this%dis%bot(m), &
660  this%dis%con%cl1(this%dis%con%jas(ipos)), &
661  this%dis%con%cl2(this%dis%con%jas(ipos)), &
662  this%dis%con%hwva(this%dis%con%jas(ipos)))
663  end if
664 
665  ! Fill row n
666  idiag = this%dis%con%ia(n)
667  call matrix_sln%add_value_pos(idxglo(ipos), cond)
668  call matrix_sln%add_value_pos(idxglo(idiag), -cond)
669 
670  ! Fill row m
671  isymcon = this%dis%con%isym(ipos)
672  idiagm = this%dis%con%ia(m)
673  call matrix_sln%add_value_pos(idxglo(isymcon), cond)
674  call matrix_sln%add_value_pos(idxglo(idiagm), -cond)
675 
Here is the call graph for this function:

◆ fn_default_flow()

subroutine gwfnpfmodule::fn_default_flow ( class(gwfnpftype)  this,
integer(i4b)  n,
integer(i4b)  m,
integer(i4b)  ipos,
class(matrixbasetype), pointer  matrix_sln,
real(dp), dimension(:), intent(inout)  rhs,
integer(i4b), dimension(:), intent(in)  idxglo,
real(dp), dimension(:), intent(inout)  hnew 
)
private

Definition at line 811 of file gwf-npf.f90.

812  class(GwfNpfType) :: this
813  integer(I4B) :: n
814  integer(I4B) :: m
815  integer(I4B) :: ipos
816  class(MatrixBaseType), pointer :: matrix_sln
817  real(DP), intent(inout), dimension(:) :: rhs
818  integer(I4B), intent(in), dimension(:) :: idxglo
819  real(DP), intent(inout), dimension(:) :: hnew
820  ! local
821  integer(I4B) :: isymcon
822  integer(I4B) :: idiag, idiagm
823  integer(I4B) :: iups
824  integer(I4B) :: idn
825  real(DP) :: cond
826  real(DP) :: consterm
827  real(DP) :: filledterm
828  real(DP) :: derv
829  real(DP) :: hds
830  real(DP) :: term
831  real(DP) :: topup
832  real(DP) :: botup
833 
834  idiag = this%dis%con%ia(n)
835  isymcon = this%dis%con%isym(ipos)
836 
837  if (this%dis%con%ihc(this%dis%con%jas(ipos)) == 0 .and. &
838  this%ivarcv == 0) then
839  return
840  end if
841 
842  ! determine upstream node
843  iups = m
844  if (hnew(m) < hnew(n)) iups = n
845  idn = n
846  if (iups == n) idn = m
847  !
848  ! -- no newton terms if upstream cell is confined
849  if (this%icelltype(iups) == 0) return
850  !
851  ! -- Set the upstream top and bot, and then recalculate for a
852  ! vertically staggered horizontal connection
853  topup = this%dis%top(iups)
854  botup = this%dis%bot(iups)
855  if (this%dis%con%ihc(this%dis%con%jas(ipos)) == 2) then
856  topup = min(this%dis%top(n), this%dis%top(m))
857  botup = max(this%dis%bot(n), this%dis%bot(m))
858  end if
859  !
860  ! get saturated conductivity for derivative
861  cond = this%condsat(this%dis%con%jas(ipos))
862  !
863  ! compute additional term
864  consterm = -cond * (hnew(iups) - hnew(idn)) !needs to use hwadi instead of hnew(idn)
865  !filledterm = cond
866  filledterm = matrix_sln%get_value_pos(idxglo(ipos))
867  derv = squadraticsaturationderivative(topup, botup, hnew(iups), &
868  this%satomega)
869  idiagm = this%dis%con%ia(m)
870  ! fill jacobian for n being the upstream node
871  if (iups == n) then
872  hds = hnew(m)
873  !isymcon = this%dis%con%isym(ii)
874  term = consterm * derv
875  rhs(n) = rhs(n) + term * hnew(n) !+ amat(idxglo(isymcon)) * (dwadi * hds - hds) !need to add dwadi
876  rhs(m) = rhs(m) - term * hnew(n) !- amat(idxglo(isymcon)) * (dwadi * hds - hds) !need to add dwadi
877  ! fill in row of n
878  call matrix_sln%add_value_pos(idxglo(idiag), term)
879  ! fill newton term in off diagonal if active cell
880  if (this%ibound(n) > 0) then
881  filledterm = matrix_sln%get_value_pos(idxglo(ipos))
882  call matrix_sln%set_value_pos(idxglo(ipos), filledterm) !* dwadi !need to add dwadi
883  end if
884  !fill row of m
885  filledterm = matrix_sln%get_value_pos(idxglo(idiagm))
886  call matrix_sln%set_value_pos(idxglo(idiagm), filledterm) !- filledterm * (dwadi - DONE) !need to add dwadi
887  ! fill newton term in off diagonal if active cell
888  if (this%ibound(m) > 0) then
889  call matrix_sln%add_value_pos(idxglo(isymcon), -term)
890  end if
891  ! fill jacobian for m being the upstream node
892  else
893  hds = hnew(n)
894  term = -consterm * derv
895  rhs(n) = rhs(n) + term * hnew(m) !+ amat(idxglo(ii)) * (dwadi * hds - hds) !need to add dwadi
896  rhs(m) = rhs(m) - term * hnew(m) !- amat(idxglo(ii)) * (dwadi * hds - hds) !need to add dwadi
897  ! fill in row of n
898  filledterm = matrix_sln%get_value_pos(idxglo(idiag))
899  call matrix_sln%set_value_pos(idxglo(idiag), filledterm) !- filledterm * (dwadi - DONE) !need to add dwadi
900  ! fill newton term in off diagonal if active cell
901  if (this%ibound(n) > 0) then
902  call matrix_sln%add_value_pos(idxglo(ipos), term)
903  end if
904  !fill row of m
905  call matrix_sln%add_value_pos(idxglo(idiagm), -term)
906  ! fill newton term in off diagonal if active cell
907  if (this%ibound(m) > 0) then
908  filledterm = matrix_sln%get_value_pos(idxglo(isymcon))
909  call matrix_sln%set_value_pos(idxglo(isymcon), filledterm) !* dwadi !need to add dwadi
910  end if
911  end if
912 
Here is the call graph for this function:

◆ highest_cell_saturation()

subroutine gwfnpfmodule::highest_cell_saturation ( class(gwfnpftype)  this,
integer(i4b), intent(in)  n,
integer(i4b), intent(in)  m,
real(dp), intent(in)  hn,
real(dp), intent(in)  hm,
real(dp), intent(inout)  satn,
real(dp), intent(inout)  satm 
)
private

Calculate the saturation based on the maximum cell bottom for two connected cells

Definition at line 718 of file gwf-npf.f90.

719  ! dummy
720  class(GwfNpfType) :: this
721  integer(I4B), intent(in) :: n, m
722  real(DP), intent(in) :: hn, hm
723  real(DP), intent(inout) :: satn, satm
724  ! local
725  integer(I4B) :: ihdbot
726  real(DP) :: botn, botm
727  real(DP) :: top, bot
728 
729  botn = this%dis%bot(n)
730  botm = this%dis%bot(m)
731 
732  ihdbot = n
733  if (botm > botn) ihdbot = m
734 
735  ! recalculate saturation if the difference in elevation between
736  ! two cells exceed a threshold value
737  if (abs(botm - botn) >= dem2) then
738  top = this%dis%top(ihdbot)
739  bot = this%dis%bot(ihdbot)
740  satn = squadraticsaturation(top, bot, hn, this%satomega)
741  satm = squadraticsaturation(top, bot, hm, this%satomega)
742  end if
Here is the call graph for this function:

◆ hy_eff()

real(dp) function gwfnpfmodule::hy_eff ( class(gwfnpftype)  this,
integer(i4b), intent(in)  n,
integer(i4b), intent(in)  m,
integer(i4b), intent(in)  ihc,
integer(i4b), intent(in), optional  ipos,
real(dp), dimension(3), intent(in), optional  vg 
)

n is primary node node number m is connected node (not used if vg is provided) ihc is horizontal indicator (0 vertical, 1 horizontal, 2 vertically staggered) ipos_opt is position of connection in ja array vg is the global unit vector that expresses the direction from which to calculate an effective hydraulic conductivity.

Definition at line 2607 of file gwf-npf.f90.

2608  ! -- return
2609  real(DP) :: hy
2610  ! -- dummy
2611  class(GwfNpfType) :: this
2612  integer(I4B), intent(in) :: n
2613  integer(I4B), intent(in) :: m
2614  integer(I4B), intent(in) :: ihc
2615  integer(I4B), intent(in), optional :: ipos
2616  real(DP), dimension(3), intent(in), optional :: vg
2617  ! -- local
2618  integer(I4B) :: iipos
2619  real(DP) :: hy11, hy22, hy33
2620  real(DP) :: ang1, ang2, ang3
2621  real(DP) :: vg1, vg2, vg3
2622  !
2623  ! -- Initialize
2624  iipos = 0
2625  if (present(ipos)) iipos = ipos
2626  hy11 = this%k11(n)
2627  hy22 = this%k11(n)
2628  hy33 = this%k11(n)
2629  hy22 = this%k22(n)
2630  hy33 = this%k33(n)
2631  !
2632  ! -- Calculate effective K based on whether connection is vertical
2633  ! or horizontal
2634  if (ihc == c3d_vertical) then
2635  !
2636  ! -- Handle rotated anisotropy case that would affect the effective
2637  ! vertical hydraulic conductivity
2638  hy = hy33
2639  if (this%iangle2 > 0) then
2640  if (present(vg)) then
2641  vg1 = vg(1)
2642  vg2 = vg(2)
2643  vg3 = vg(3)
2644  else
2645  call this%dis%connection_normal(n, m, ihc, vg1, vg2, vg3, iipos)
2646  end if
2647  ang1 = this%angle1(n)
2648  ang2 = this%angle2(n)
2649  ang3 = dzero
2650  if (this%iangle3 > 0) ang3 = this%angle3(n)
2651  hy = hyeff(hy11, hy22, hy33, ang1, ang2, ang3, vg1, vg2, vg3, &
2652  this%iavgkeff)
2653  end if
2654  !
2655  else
2656  !
2657  ! -- Handle horizontal case
2658  hy = hy11
2659  if (this%ik22 > 0) then
2660  if (present(vg)) then
2661  vg1 = vg(1)
2662  vg2 = vg(2)
2663  vg3 = vg(3)
2664  else
2665  call this%dis%connection_normal(n, m, ihc, vg1, vg2, vg3, iipos)
2666  end if
2667  ang1 = dzero
2668  ang2 = dzero
2669  ang3 = dzero
2670  if (this%iangle1 > 0) then
2671  ang1 = this%angle1(n)
2672  if (this%iangle2 > 0) then
2673  ang2 = this%angle2(n)
2674  if (this%iangle3 > 0) ang3 = this%angle3(n)
2675  end if
2676  end if
2677  hy = hyeff(hy11, hy22, hy33, ang1, ang2, ang3, vg1, vg2, vg3, &
2678  this%iavgkeff)
2679  end if
2680  !
2681  end if
Here is the call graph for this function:

◆ increase_edge_count()

subroutine gwfnpfmodule::increase_edge_count ( class(gwfnpftype)  this,
integer(i4b), intent(in)  nedges 
)
private

This must be called before the npfallocate_arrays routine, which is called from npfar.

Definition at line 2997 of file gwf-npf.f90.

2998  ! -- dummy
2999  class(GwfNpfType) :: this
3000  integer(I4B), intent(in) :: nedges
3001  !
3002  this%nedges = this%nedges + nedges

◆ log_griddata()

subroutine gwfnpfmodule::log_griddata ( class(gwfnpftype)  this,
type(gwfnpfparamfoundtype), intent(in)  found 
)

Definition at line 1769 of file gwf-npf.f90.

1770  ! -- modules
1772  ! -- dummy
1773  class(GwfNpfType) :: this
1774  type(GwfNpfParamFoundType), intent(in) :: found
1775  !
1776  write (this%iout, '(1x,a)') 'Setting NPF Griddata'
1777  !
1778  if (found%icelltype) then
1779  write (this%iout, '(4x,a)') 'ICELLTYPE set from input file'
1780  end if
1781  !
1782  if (found%k) then
1783  write (this%iout, '(4x,a)') 'K set from input file'
1784  end if
1785  !
1786  if (found%k33) then
1787  write (this%iout, '(4x,a)') 'K33 set from input file'
1788  else
1789  write (this%iout, '(4x,a)') 'K33 not provided. Setting K33 = K.'
1790  end if
1791  !
1792  if (found%k22) then
1793  write (this%iout, '(4x,a)') 'K22 set from input file'
1794  else
1795  write (this%iout, '(4x,a)') 'K22 not provided. Setting K22 = K.'
1796  end if
1797  !
1798  if (found%wetdry) then
1799  write (this%iout, '(4x,a)') 'WETDRY set from input file'
1800  end if
1801  !
1802  if (found%angle1) then
1803  write (this%iout, '(4x,a)') 'ANGLE1 set from input file'
1804  end if
1805  !
1806  if (found%angle2) then
1807  write (this%iout, '(4x,a)') 'ANGLE2 set from input file'
1808  end if
1809  !
1810  if (found%angle3) then
1811  write (this%iout, '(4x,a)') 'ANGLE3 set from input file'
1812  end if
1813  !
1814  write (this%iout, '(1x,a,/)') 'End Setting NPF Griddata'

◆ log_options()

subroutine gwfnpfmodule::log_options ( class(gwfnpftype)  this,
type(gwfnpfparamfoundtype), intent(in)  found 
)
private

Definition at line 1515 of file gwf-npf.f90.

1516  ! -- modules
1517  use kindmodule, only: lgp
1519  ! -- dummy
1520  class(GwfNpftype) :: this
1521  ! -- locals
1522  type(GwfNpfParamFoundType), intent(in) :: found
1523  !
1524  write (this%iout, '(1x,a)') 'Setting NPF Options'
1525  if (found%iprflow) &
1526  write (this%iout, '(4x,a)') 'Cell-by-cell flow information will be printed &
1527  &to listing file whenever ICBCFL is not zero.'
1528  if (found%ipakcb) &
1529  write (this%iout, '(4x,a)') 'Cell-by-cell flow information will be saved &
1530  &to binary file whenever ICBCFL is not zero.'
1531  if (found%cellavg) &
1532  write (this%iout, '(4x,a,i0)') 'Alternative cell averaging [1=logarithmic, &
1533  &2=AMT-LMK, 3=AMT-HMK] set to: ', &
1534  this%icellavg
1535  if (found%ithickstrt) &
1536  write (this%iout, '(4x,a)') 'THICKSTRT option has been activated.'
1537  if (found%ihighcellsat) &
1538  write (this%iout, '(4x,a)') 'HIGHEST_CELL_SATURATION option &
1539  &has been activated.'
1540  if (found%iperched) &
1541  write (this%iout, '(4x,a)') 'Vertical flow will be adjusted for perched &
1542  &conditions.'
1543  if (found%ivarcv) &
1544  write (this%iout, '(4x,a)') 'Vertical conductance varies with water table.'
1545  if (found%idewatcv) &
1546  write (this%iout, '(4x,a)') 'Vertical conductance is calculated using &
1547  &only the saturated thickness and properties &
1548  &of the overlying cell if the head in the &
1549  &underlying cell is below its top.'
1550  if (found%ixt3d) write (this%iout, '(4x,a)') 'XT3D formulation is selected.'
1551  if (found%ixt3drhs) &
1552  write (this%iout, '(4x,a)') 'XT3D RHS formulation is selected.'
1553  if (found%isavspdis) &
1554  write (this%iout, '(4x,a)') 'Specific discharge will be calculated at cell &
1555  &centers and written to DATA-SPDIS in budget &
1556  &file when requested.'
1557  if (found%isavsat) &
1558  write (this%iout, '(4x,a)') 'Saturation will be written to DATA-SAT in &
1559  &budget file when requested.'
1560  if (found%ik22overk) &
1561  write (this%iout, '(4x,a)') 'Values specified for K22 are anisotropy &
1562  &ratios and will be multiplied by K before &
1563  &being used in calculations.'
1564  if (found%ik33overk) &
1565  write (this%iout, '(4x,a)') 'Values specified for K33 are anisotropy &
1566  &ratios and will be multiplied by K before &
1567  &being used in calculations.'
1568  if (found%inewton) &
1569  write (this%iout, '(4x,a)') 'NEWTON-RAPHSON method disabled for unconfined &
1570  &cells'
1571  if (found%satomega) &
1572  write (this%iout, '(4x,a,1pg15.6)') 'Saturation omega: ', this%satomega
1573  if (found%irewet) &
1574  write (this%iout, '(4x,a)') 'Rewetting is active.'
1575  if (found%wetfct) &
1576  write (this%iout, '(4x,a,1pg15.6)') &
1577  'Wetting factor (WETFCT) has been set to: ', this%wetfct
1578  if (found%iwetit) &
1579  write (this%iout, '(4x,a,i5)') &
1580  'Wetting iteration interval (IWETIT) has been set to: ', this%iwetit
1581  if (found%ihdwet) &
1582  write (this%iout, '(4x,a,i5)') &
1583  'Head rewet equation (IHDWET) has been set to: ', this%ihdwet
1584  write (this%iout, '(1x,a,/)') 'End Setting NPF Options'
This module defines variable data types.
Definition: kind.f90:8

◆ npf_ac()

subroutine gwfnpfmodule::npf_ac ( class(gwfnpftype)  this,
integer(i4b), intent(in)  moffset,
type(sparsematrix), intent(inout)  sparse 
)

Definition at line 288 of file gwf-npf.f90.

289  ! -- modules
290  use sparsemodule, only: sparsematrix
291  ! -- dummy
292  class(GwfNpftype) :: this
293  integer(I4B), intent(in) :: moffset
294  type(sparsematrix), intent(inout) :: sparse
295  !
296  ! -- Add extended neighbors (neighbors of neighbors)
297  if (this%ixt3d /= 0) call this%xt3d%xt3d_ac(moffset, sparse)

◆ npf_ad()

subroutine gwfnpfmodule::npf_ad ( class(gwfnpftype)  this,
integer(i4b), intent(in)  nodes,
real(dp), dimension(nodes), intent(inout)  hold,
real(dp), dimension(nodes), intent(inout)  hnew,
integer(i4b), intent(in)  irestore 
)
private

Sets hold (head old) to bot whenever a wettable cell is dry

Definition at line 430 of file gwf-npf.f90.

431  ! -- modules
432  use tdismodule, only: kper, kstp
433  !
434  implicit none
435  ! -- dummy
436  class(GwfNpfType) :: this
437  integer(I4B), intent(in) :: nodes
438  real(DP), dimension(nodes), intent(inout) :: hold
439  real(DP), dimension(nodes), intent(inout) :: hnew
440  integer(I4B), intent(in) :: irestore
441  ! -- local
442  integer(I4B) :: n
443  !
444  ! -- loop through all cells and set hold=bot if wettable cell is dry
445  if (this%irewet > 0) then
446  do n = 1, this%dis%nodes
447  if (this%wetdry(n) == dzero) cycle
448  if (this%ibound(n) /= 0) cycle
449  hold(n) = this%dis%bot(n)
450  end do
451  !
452  ! -- if restore state, then set hnew to DRY if it is a dry wettable cell
453  do n = 1, this%dis%nodes
454  if (this%wetdry(n) == dzero) cycle
455  if (this%ibound(n) /= 0) cycle
456  hnew(n) = dhdry
457  end do
458  end if
459  !
460  ! -- TVK
461  if (this%intvk /= 0) then
462  call this%tvk%ad()
463  end if
464  !
465  ! -- VSC
466  ! -- Hit the TVK-updated K's with VSC correction before calling/updating condsat
467  if (this%invsc /= 0) then
468  call this%vsc%update_k_with_vsc()
469  end if
470  !
471  ! -- If any K values have changed, we need to update CONDSAT or XT3D arrays
472  if (this%kchangeper == kper .and. this%kchangestp == kstp) then
473  if (this%ixt3d == 0) then
474  !
475  ! -- Update the saturated conductance for all connections
476  ! -- of the affected nodes
477  do n = 1, this%dis%nodes
478  if (this%nodekchange(n) == 1) then
479  call this%calc_condsat(n, .false.)
480  end if
481  end do
482  else
483  !
484  ! -- Recompute XT3D coefficients for permanently confined connections
485  if (this%xt3d%lamatsaved .and. .not. this%xt3d%ldispersion) then
486  call this%xt3d%xt3d_fcpc(this%dis%nodes, .true.)
487  end if
488  end if
489  end if
integer(i4b), pointer, public kstp
current time step number
Definition: tdis.f90:27
integer(i4b), pointer, public kper
current stress period number
Definition: tdis.f90:26

◆ npf_ar()

subroutine gwfnpfmodule::npf_ar ( class(gwfnpftype)  this,
type(gwfictype), intent(in), pointer  ic,
type(gwfvsctype), intent(in), pointer  vsc,
integer(i4b), dimension(:), intent(inout), pointer, contiguous  ibound,
real(dp), dimension(:), intent(inout), pointer, contiguous  hnew 
)
private

Allocate remaining package arrays, preprocess the input data and call *_ar on xt3d, when active.

Parameters
thisinstance of the NPF package
[in]icinitial conditions
[in]vscviscosity package
[in,out]iboundmodel ibound array
[in,out]hnewpointer to model head array

Definition at line 316 of file gwf-npf.f90.

317  ! -- modules
320  ! -- dummy
321  class(GwfNpftype) :: this !< instance of the NPF package
322  type(GwfIcType), pointer, intent(in) :: ic !< initial conditions
323  type(GwfVscType), pointer, intent(in) :: vsc !< viscosity package
324  integer(I4B), dimension(:), pointer, contiguous, intent(inout) :: ibound !< model ibound array
325  real(DP), dimension(:), pointer, contiguous, intent(inout) :: hnew !< pointer to model head array
326  ! -- local
327  integer(I4B) :: n
328  !
329  ! -- Store pointers to arguments that were passed in
330  this%ic => ic
331  this%ibound => ibound
332  this%hnew => hnew
333  !
334  if (this%icalcspdis == 1) then
335  call mem_reallocate(this%spdis, 3, this%dis%nodes, 'SPDIS', this%memoryPath)
336  call mem_reallocate(this%nodedge, this%nedges, 'NODEDGE', this%memoryPath)
337  call mem_reallocate(this%ihcedge, this%nedges, 'IHCEDGE', this%memoryPath)
338  call mem_reallocate(this%propsedge, 5, this%nedges, 'PROPSEDGE', &
339  this%memoryPath)
340  call mem_reallocate(this%iedge_ptr, this%dis%nodes + 1, &
341  'NREDGESNODE', this%memoryPath)
342  call mem_reallocate(this%edge_idxs, this%nedges, &
343  'EDGEIDXS', this%memoryPath)
344 
345  do n = 1, this%nedges
346  this%edge_idxs(n) = 0
347  end do
348  do n = 1, this%dis%nodes
349  this%iedge_ptr(n) = 0
350  this%spdis(:, n) = dzero
351  end do
352  end if
353  !
354  ! -- Store pointer to VSC if active
355  if (this%invsc /= 0) then
356  this%vsc => vsc
357  end if
358  !
359  ! -- allocate arrays to store original user input in case TVK/VSC modify them
360  if (this%invsc > 0) then
361  !
362  ! -- Reallocate arrays that store user-input values.
363  call mem_reallocate(this%k11input, this%dis%nodes, 'K11INPUT', &
364  this%memoryPath)
365  call mem_reallocate(this%k22input, this%dis%nodes, 'K22INPUT', &
366  this%memoryPath)
367  call mem_reallocate(this%k33input, this%dis%nodes, 'K33INPUT', &
368  this%memoryPath)
369  ! Allocate arrays that will store the original K values. When VSC active,
370  ! the current Kxx arrays carry the viscosity-adjusted K values.
371  ! This approach leverages existing functionality that makes use of K.
372  call this%store_original_k_arrays(this%dis%nodes, this%dis%njas)
373  end if
374  !
375  ! -- preprocess data
376  call this%preprocess_input()
377  !
378  ! -- xt3d
379  ! -- Terminate if the DISU ANGLDEGX values are inconsistent and this
380  ! package requires ANGLDEGX (it has no effect otherwise)
381  if (this%ixt3d /= 0 .or. this%ik22 /= 0 .or. this%icalcspdis /= 0) then
382  select type (dis => this%dis)
383  type is (disutype)
384  if (dis%nangldegxerr > 0) then
385  write (errmsg, '(a,1x,i0,1x,a)') &
386  'ANGLDEGX values in the DISU Package are inconsistent for', &
387  dis%nangldegxerr, 'cell faces (see the warnings written after &
388  &the DISU Package input in the model listing file). ANGLDEGX &
389  &must be correct because it is required input for the NPF &
390  &Package when XT3D, K22, or SAVE_SPECIFIC_DISCHARGE is specified.'
391  call store_error(errmsg)
392  call store_error_filename(dis%input_fname)
393  end if
394  end select
395  end if
396  !
397  if (this%ixt3d /= 0) then
398  call this%xt3d%xt3d_ar(ibound, this%k11, this%ik33, this%k33, &
399  this%sat, this%ik22, this%k22, &
400  this%iangle1, this%iangle2, this%iangle3, &
401  this%angle1, this%angle2, this%angle3, &
402  this%inewton, this%icelltype)
403  end if
404  !
405  ! -- TVK
406  if (this%intvk /= 0) then
407  call this%tvk%ar(this%dis)
408  end if
Here is the call graph for this function:

◆ npf_cf()

subroutine gwfnpfmodule::npf_cf ( class(gwfnpftype)  this,
integer(i4b)  kiter,
integer(i4b), intent(in)  nodes,
real(dp), dimension(nodes), intent(inout)  hnew 
)

Definition at line 494 of file gwf-npf.f90.

495  class(GwfNpfType) :: this
496  integer(I4B) :: kiter
497  integer(I4B), intent(in) :: nodes
498  real(DP), intent(inout), dimension(nodes) :: hnew
499  ! local
500  integer(I4B) :: iform
501 
502  ! Perform wetting and drying
503  if (this%inewton /= 1) then
504  call this%wd(kiter, hnew)
505  end if
506 
507  ! Each active formulation runs over all cells and adds its
508  ! terms; the default conductance formulation is always active.
509  call this%default_form%cf(kiter)
510  do iform = 1, max_ext_flow_forms
511  if (associated(this%flow_formulations(iform)%form)) then
512  call this%flow_formulations(iform)%form%cf(kiter)
513  end if
514  end do
515 

◆ npf_cq()

subroutine gwfnpfmodule::npf_cq ( class(gwfnpftype)  this,
real(dp), dimension(:), intent(inout)  hnew,
real(dp), dimension(:), intent(inout)  flowja 
)
private

Definition at line 964 of file gwf-npf.f90.

965  ! -- dummy
966  class(GwfNpfType) :: this
967  real(DP), intent(inout), dimension(:) :: hnew
968  real(DP), intent(inout), dimension(:) :: flowja
969  ! -- local
970  integer(I4B) :: iform
971  !
972  ! -- Calculate the flow across each cell face and store in flowja
973  !
974  if (this%ixt3d /= 0) then
975  call this%xt3d%xt3d_flowja(hnew, flowja)
976  else
977  ! Each active formulation runs over all connections and adds its
978  ! flows; the default conductance formulation is always active.
979  call this%default_form%cq(hnew, flowja)
980  do iform = 1, max_ext_flow_forms
981  if (associated(this%flow_formulations(iform)%form)) then
982  call this%flow_formulations(iform)%form%cq(hnew, flowja)
983  end if
984  end do
985  end if

◆ npf_cr()

subroutine, public gwfnpfmodule::npf_cr ( type(gwfnpftype), pointer  npfobj,
character(len=*), intent(in)  name_model,
character(len=*), intent(in)  input_mempath,
integer(i4b), intent(in)  inunit,
integer(i4b), intent(in)  iout 
)

Definition at line 188 of file gwf-npf.f90.

189  ! -- modules
190  use kindmodule, only: lgp
192  ! -- dummy
193  type(GwfNpfType), pointer :: npfobj
194  character(len=*), intent(in) :: name_model
195  character(len=*), intent(in) :: input_mempath
196  integer(I4B), intent(in) :: inunit
197  integer(I4B), intent(in) :: iout
198  ! -- formats
199  character(len=*), parameter :: fmtheader = &
200  "(1x, /1x, 'NPF -- NODE PROPERTY FLOW PACKAGE, VERSION 1, 3/30/2015', &
201  &' INPUT READ FROM MEMPATH: ', A, /)"
202  !
203  ! -- Create the object
204  allocate (npfobj)
205  !
206  ! -- create name and memory path
207  call npfobj%set_names(1, name_model, 'NPF', 'NPF', input_mempath)
208  !
209  ! -- Allocate scalars
210  call npfobj%allocate_scalars()
211  !
212  ! -- Set variables
213  npfobj%inunit = inunit
214  npfobj%iout = iout
215  !
216  ! -- check if npf is enabled
217  if (inunit > 0) then
218  !
219  ! -- Print a message identifying the node property flow package.
220  write (iout, fmtheader) input_mempath
221  end if
222 
223  ! allocate spdis structure
224  allocate (npfobj%spdis_wa)
225 
Here is the caller graph for this function:

◆ npf_da()

subroutine gwfnpfmodule::npf_da ( class(gwfnpftype)  this)

Definition at line 1210 of file gwf-npf.f90.

1211  ! -- modules
1213  use simvariablesmodule, only: idm_context
1214  ! -- dummy
1215  class(GwfNpftype) :: this
1216 
1217  ! free spdis work structure
1218  if (this%icalcspdis == 1 .and. this%spdis_wa%is_created()) &
1219  call this%spdis_wa%destroy()
1220  deallocate (this%spdis_wa)
1221  !
1222  ! -- Deallocate input memory
1223  call memorystore_remove(this%name_model, 'NPF', idm_context)
1224  !
1225  ! -- TVK
1226  if (this%intvk /= 0) then
1227  call this%tvk%da()
1228  deallocate (this%tvk)
1229  end if
1230  !
1231  ! -- VSC
1232  if (this%invsc /= 0) then
1233  nullify (this%vsc)
1234  end if
1235  !
1236  ! -- Scalars
1237  call mem_deallocate(this%iname)
1238  call mem_deallocate(this%ixt3d)
1239  call mem_deallocate(this%ixt3drhs)
1240  call mem_deallocate(this%satomega)
1241  call mem_deallocate(this%hnoflo)
1242  call mem_deallocate(this%hdry)
1243  call mem_deallocate(this%icellavg)
1244  call mem_deallocate(this%iavgkeff)
1245  call mem_deallocate(this%ik22)
1246  call mem_deallocate(this%ik33)
1247  call mem_deallocate(this%iperched)
1248  call mem_deallocate(this%ivarcv)
1249  call mem_deallocate(this%idewatcv)
1250  call mem_deallocate(this%ithickstrt)
1251  call mem_deallocate(this%ihighcellsat)
1252  call mem_deallocate(this%isavspdis)
1253  call mem_deallocate(this%isavsat)
1254  call mem_deallocate(this%icalcspdis)
1255  call mem_deallocate(this%irewet)
1256  call mem_deallocate(this%wetfct)
1257  call mem_deallocate(this%iwetit)
1258  call mem_deallocate(this%ihdwet)
1259  call mem_deallocate(this%ibotnode)
1260  call mem_deallocate(this%iwetdry)
1261  call mem_deallocate(this%iangle1)
1262  call mem_deallocate(this%iangle2)
1263  call mem_deallocate(this%iangle3)
1264  call mem_deallocate(this%nedges)
1265  call mem_deallocate(this%lastedge)
1266  call mem_deallocate(this%ik22overk)
1267  call mem_deallocate(this%ik33overk)
1268  call mem_deallocate(this%intvk)
1269  call mem_deallocate(this%invsc)
1270  call mem_deallocate(this%kchangeper)
1271  call mem_deallocate(this%kchangestp)
1272  !
1273  ! -- Deallocate arrays
1274  deallocate (this%aname)
1275  call mem_deallocate(this%ithickstartflag)
1276  call mem_deallocate(this%icelltype)
1277  call mem_deallocate(this%k11)
1278  call mem_deallocate(this%k22)
1279  call mem_deallocate(this%k33)
1280  call mem_deallocate(this%krel)
1281  call mem_deallocate(this%k11input)
1282  call mem_deallocate(this%k22input)
1283  call mem_deallocate(this%k33input)
1284  call mem_deallocate(this%sat, 'SAT', this%memoryPath)
1285  call mem_deallocate(this%condsat)
1286  call mem_deallocate(this%wetdry)
1287  call mem_deallocate(this%angle1)
1288  call mem_deallocate(this%angle2)
1289  call mem_deallocate(this%angle3)
1290  call mem_deallocate(this%nodedge)
1291  call mem_deallocate(this%ihcedge)
1292  call mem_deallocate(this%propsedge)
1293  call mem_deallocate(this%iedge_ptr)
1294  call mem_deallocate(this%edge_idxs)
1295  call mem_deallocate(this%spdis, 'SPDIS', this%memoryPath)
1296  call mem_deallocate(this%nodekchange)
1297  call mem_deallocate(this%iformulation)
1298  !
1299  ! -- deallocate the default conductance formulation
1300  if (associated(this%default_form)) then
1301  deallocate (this%default_form)
1302  this%default_form => null()
1303  end if
1304  !
1305  ! -- deallocate parent
1306  call this%NumericalPackageType%da()
1307 
1308  ! pointers
1309  this%hnew => null()
1310 
subroutine, public memorystore_remove(component, subcomponent, context)
This module contains simulation variables.
Definition: SimVariables.f90:9
character(len=linelength) idm_context
Here is the call graph for this function:

◆ npf_df()

subroutine gwfnpfmodule::npf_df ( class(gwfnpftype)  this,
class(disbasetype), intent(inout), pointer  dis,
type(xt3dtype), pointer  xt3d,
integer(i4b), intent(in)  ingnc,
integer(i4b), intent(in)  invsc,
type(gwfnpfoptionstype), intent(in), optional  npf_options 
)

This is a hybrid routine: it either reads the options for this package from the input file, or the optional argument

Parameters
npf_optionsshould be passed. A consistency check is performed, and finally xt3d_df is called, when enabled.
thisinstance of the NPF package
[in,out]disthe pointer to the discretization
xt3dthe pointer to the XT3D 'package'
[in]ingncghostnodes enabled? (>0 means yes)
[in]invscviscosity enabled? (>0 means yes)
[in]npf_optionsthe optional options, for when not constructing from file

Definition at line 235 of file gwf-npf.f90.

236  ! -- modules
237  use simmodule, only: store_error
238  use xt3dmodule, only: xt3d_cr
239  ! -- dummy
240  class(GwfNpftype) :: this !< instance of the NPF package
241  class(DisBaseType), pointer, intent(inout) :: dis !< the pointer to the discretization
242  type(Xt3dType), pointer :: xt3d !< the pointer to the XT3D 'package'
243  integer(I4B), intent(in) :: ingnc !< ghostnodes enabled? (>0 means yes)
244  integer(I4B), intent(in) :: invsc !< viscosity enabled? (>0 means yes)
245  type(GwfNpfOptionsType), optional, intent(in) :: npf_options !< the optional options, for when not constructing from file
246  !
247  ! -- Set a pointer to dis
248  this%dis => dis
249  !
250  ! -- Set flag signifying whether vsc is active
251  if (invsc > 0) this%invsc = invsc
252  !
253  if (.not. present(npf_options)) then
254  !
255  ! -- source options
256  call this%source_options()
257  !
258  ! -- allocate arrays
259  call this%allocate_arrays(this%dis%nodes, this%dis%njas)
260  !
261  ! -- source griddata, set, and convert/check the input
262  call this%source_griddata()
263  call this%prepcheck()
264  else
265  call this%set_options(npf_options)
266  !
267  ! -- allocate arrays
268  call this%allocate_arrays(this%dis%nodes, this%dis%njas)
269  end if
270  !
271  call this%check_options()
272  !
273  ! -- Save pointer to xt3d object
274  this%xt3d => xt3d
275  if (this%ixt3d /= 0) xt3d%ixt3d = this%ixt3d
276  call this%xt3d%xt3d_df(dis)
277  !
278  ! -- Ensure GNC and XT3D are not both on at the same time
279  if (this%ixt3d /= 0 .and. ingnc > 0) then
280  call store_error('Error in model '//trim(this%name_model)// &
281  '. The XT3D option cannot be used with the GNC &
282  &Package.', terminate=.true.)
283  end if
subroutine, public xt3d_cr(xt3dobj, name_model, inunit, iout, ldispopt)
Create a new xt3d object.
Here is the call graph for this function:

◆ npf_fc()

subroutine gwfnpfmodule::npf_fc ( class(gwfnpftype)  this,
integer(i4b)  kiter,
class(matrixbasetype), pointer  matrix_sln,
integer(i4b), dimension(:), intent(in)  idxglo,
real(dp), dimension(:), intent(inout)  rhs,
real(dp), dimension(:), intent(inout)  hnew 
)
private
Parameters
thisthis instance
kiterouter iteration number
matrix_slnthe system to be formulated
[in]idxglolookup table from local to global connection number
[in,out]rhsthe righthandside vector
[in,out]hnewthe new head values

Definition at line 561 of file gwf-npf.f90.

562  class(GwfNpfType) :: this !< this instance
563  integer(I4B) :: kiter !< outer iteration number
564  class(MatrixBaseType), pointer :: matrix_sln !< the system to be formulated
565  integer(I4B), intent(in), dimension(:) :: idxglo !< lookup table from local to global connection number
566  real(DP), intent(inout), dimension(:) :: rhs !< the righthandside vector
567  real(DP), intent(inout), dimension(:) :: hnew !< the new head values
568  ! local
569  integer(I4B) :: iform
570 
571  if (this%ixt3d /= 0) then
572  call this%xt3d%xt3d_fc(kiter, matrix_sln, idxglo, rhs, hnew)
573  else
574  ! Each active formulation runs over all connections and adds its
575  ! terms; the default conductance formulation is always active.
576  call this%default_form%fc(kiter, matrix_sln, idxglo, rhs, hnew)
577  do iform = 1, max_ext_flow_forms
578  if (associated(this%flow_formulations(iform)%form)) then
579  call this%flow_formulations(iform)%form%fc(kiter, matrix_sln, &
580  idxglo, rhs, hnew)
581  end if
582  end do
583  end if
584 

◆ npf_fn()

subroutine gwfnpfmodule::npf_fn ( class(gwfnpftype)  this,
integer(i4b)  kiter,
class(matrixbasetype), pointer  matrix_sln,
integer(i4b), dimension(:), intent(in)  idxglo,
real(dp), dimension(:), intent(inout)  rhs,
real(dp), dimension(:), intent(inout)  hnew 
)
private

Definition at line 747 of file gwf-npf.f90.

748  ! -- dummy
749  class(GwfNpfType) :: this
750  integer(I4B) :: kiter
751  class(MatrixBaseType), pointer :: matrix_sln
752  integer(I4B), intent(in), dimension(:) :: idxglo
753  real(DP), intent(inout), dimension(:) :: rhs
754  real(DP), intent(inout), dimension(:) :: hnew
755  ! -- local
756  integer(I4B) :: nodes, nja
757  integer(I4B) :: iform
758  !
759  ! -- add newton terms to solution matrix
760  nodes = this%dis%nodes
761  nja = this%dis%con%nja
762  if (this%ixt3d /= 0) then
763  call this%xt3d%xt3d_fn(kiter, nodes, nja, matrix_sln, idxglo, rhs, hnew)
764  else
765  ! Each active formulation runs over all connections and adds its
766  ! newton terms; the default conductance formulation is always active.
767  call this%default_form%fn(kiter, matrix_sln, idxglo, rhs, hnew)
768  do iform = 1, max_ext_flow_forms
769  if (associated(this%flow_formulations(iform)%form)) then
770  call this%flow_formulations(iform)%form%fn(kiter, matrix_sln, &
771  idxglo, rhs, hnew)
772  end if
773  end do
774  end if

◆ npf_mc()

subroutine gwfnpfmodule::npf_mc ( class(gwfnpftype)  this,
integer(i4b), intent(in)  moffset,
class(matrixbasetype), pointer  matrix_sln 
)

Definition at line 302 of file gwf-npf.f90.

303  ! -- dummy
304  class(GwfNpftype) :: this
305  integer(I4B), intent(in) :: moffset
306  class(MatrixBaseType), pointer :: matrix_sln
307  !
308  if (this%ixt3d /= 0) call this%xt3d%xt3d_mc(moffset, matrix_sln)

◆ npf_nur()

subroutine gwfnpfmodule::npf_nur ( class(gwfnpftype)  this,
integer(i4b), intent(in)  neqmod,
real(dp), dimension(neqmod), intent(inout)  x,
real(dp), dimension(neqmod), intent(in)  xtemp,
real(dp), dimension(neqmod), intent(inout)  dx,
integer(i4b), intent(inout)  inewtonur,
real(dp), intent(inout)  dxmax,
integer(i4b), intent(inout)  locmax 
)
private

Under-relaxation of Groundwater Flow Model Heads for current outer iteration using the cell bottoms at the bottom of the model

Definition at line 920 of file gwf-npf.f90.

921  ! -- dummy
922  class(GwfNpfType) :: this
923  integer(I4B), intent(in) :: neqmod
924  real(DP), dimension(neqmod), intent(inout) :: x
925  real(DP), dimension(neqmod), intent(in) :: xtemp
926  real(DP), dimension(neqmod), intent(inout) :: dx
927  integer(I4B), intent(inout) :: inewtonur
928  real(DP), intent(inout) :: dxmax
929  integer(I4B), intent(inout) :: locmax
930  ! -- local
931  integer(I4B) :: n
932  integer(I4B) :: ibot
933  real(DP) :: botm
934  real(DP) :: xx
935  real(DP) :: dxx
936  !
937  ! -- Newton-Raphson under-relaxation
938  do n = 1, this%dis%nodes
939  if (this%ibound(n) < 1) cycle
940  ibot = this%ibotnode(n)
941  ! Newton-Raphson under-relaxation is only applied to convertible cells where
942  ! the bottom cell in a stack is convertible
943  if (this%icelltype(n) > 0 .and. this%icelltype(ibot) > 0) then
944  botm = this%dis%bot(ibot)
945  ! Newton-Raphson under-relaxation applied when solution head is
946  ! below the bottom of the model
947  if (x(n) < botm) then
948  inewtonur = 1
949  xx = xtemp(n) * (done - dp9) + botm * dp9
950  dxx = xx - xtemp(n)
951  if (abs(dxx) > abs(dxmax)) then
952  locmax = n
953  dxmax = dxx
954  end if
955  x(n) = xx
956  dx(n) = xtemp(n) - x(n)
957  end if
958  end if
959  end do

◆ npf_print_model_flows()

subroutine gwfnpfmodule::npf_print_model_flows ( class(gwfnpftype)  this,
integer(i4b), intent(in)  ibudfl,
real(dp), dimension(:), intent(inout)  flowja 
)
private

Definition at line 1171 of file gwf-npf.f90.

1172  ! -- modules
1173  use tdismodule, only: kper, kstp
1174  use constantsmodule, only: lenbigline
1175  ! -- dummy
1176  class(GwfNpfType) :: this
1177  integer(I4B), intent(in) :: ibudfl
1178  real(DP), intent(inout), dimension(:) :: flowja
1179  ! -- local
1180  character(len=LENBIGLINE) :: line
1181  character(len=30) :: tempstr
1182  integer(I4B) :: n, ipos, m
1183  real(DP) :: qnm
1184  ! -- formats
1185  character(len=*), parameter :: fmtiprflow = &
1186  &"(/,4x,'CALCULATED INTERCELL FLOW FOR PERIOD ', i0, ' STEP ', i0)"
1187  !
1188  ! -- Write flowja to list file if requested
1189  if (ibudfl /= 0 .and. this%iprflow > 0) then
1190  write (this%iout, fmtiprflow) kper, kstp
1191  do n = 1, this%dis%nodes
1192  line = ''
1193  call this%dis%noder_to_string(n, tempstr)
1194  line = trim(tempstr)//':'
1195  do ipos = this%dis%con%ia(n) + 1, this%dis%con%ia(n + 1) - 1
1196  m = this%dis%con%ja(ipos)
1197  call this%dis%noder_to_string(m, tempstr)
1198  line = trim(line)//' '//trim(tempstr)
1199  qnm = flowja(ipos)
1200  write (tempstr, '(1pg15.6)') qnm
1201  line = trim(line)//' '//trim(adjustl(tempstr))
1202  end do
1203  write (this%iout, '(a)') trim(line)
1204  end do
1205  end if
integer(i4b), parameter lenbigline
maximum length of a big line
Definition: Constants.f90:15

◆ npf_rp()

subroutine gwfnpfmodule::npf_rp ( class(gwfnpftype)  this)

Read and prepare NPF stress period data.

Definition at line 415 of file gwf-npf.f90.

416  implicit none
417  ! -- dummy
418  class(GwfNpfType) :: this
419  !
420  ! -- TVK
421  if (this%intvk /= 0) then
422  call this%tvk%rp()
423  end if

◆ npf_save_model_flows()

subroutine gwfnpfmodule::npf_save_model_flows ( class(gwfnpftype)  this,
real(dp), dimension(:), intent(in)  flowja,
integer(i4b), intent(in)  icbcfl,
integer(i4b), intent(in)  icbcun 
)
private

Definition at line 1134 of file gwf-npf.f90.

1135  ! -- dummy
1136  class(GwfNpfType) :: this
1137  real(DP), dimension(:), intent(in) :: flowja
1138  integer(I4B), intent(in) :: icbcfl
1139  integer(I4B), intent(in) :: icbcun
1140  ! -- local
1141  integer(I4B) :: ibinun
1142  !
1143  ! -- Set unit number for binary output
1144  if (this%ipakcb < 0) then
1145  ibinun = icbcun
1146  elseif (this%ipakcb == 0) then
1147  ibinun = 0
1148  else
1149  ibinun = this%ipakcb
1150  end if
1151  if (icbcfl == 0) ibinun = 0
1152  !
1153  ! -- Write the face flows if requested
1154  if (ibinun /= 0) then
1155  call this%dis%record_connection_array(flowja, ibinun, this%iout)
1156  end if
1157  !
1158  ! -- Calculate specific discharge at cell centers and write, if requested
1159  if (this%isavspdis /= 0) then
1160  if (ibinun /= 0) call this%sav_spdis(ibinun)
1161  end if
1162  !
1163  ! -- Save saturation, if requested
1164  if (this%isavsat /= 0) then
1165  if (ibinun /= 0) call this%sav_sat(ibinun)
1166  end if

◆ prepare_edge_lookup()

subroutine gwfnpfmodule::prepare_edge_lookup ( class(gwfnpftype)  this)
private

Definition at line 3063 of file gwf-npf.f90.

3064  class(GwfNpfType) :: this
3065  ! local
3066  integer(I4B) :: i, inode, iedge
3067  integer(I4B) :: n, start, end
3068  integer(I4B) :: prev_cnt, strt_idx, ipos
3069 
3070  do i = 1, size(this%iedge_ptr)
3071  this%iedge_ptr(i) = 0
3072  end do
3073  do i = 1, size(this%edge_idxs)
3074  this%edge_idxs(i) = 0
3075  end do
3076 
3077  ! count
3078  do iedge = 1, this%nedges
3079  n = this%nodedge(iedge)
3080  this%iedge_ptr(n) = this%iedge_ptr(n) + 1
3081  end do
3082 
3083  ! determine start indexes
3084  prev_cnt = this%iedge_ptr(1)
3085  this%iedge_ptr(1) = 1
3086  do inode = 2, this%dis%nodes + 1
3087  strt_idx = this%iedge_ptr(inode - 1) + prev_cnt
3088  prev_cnt = this%iedge_ptr(inode)
3089  this%iedge_ptr(inode) = strt_idx
3090  end do
3091 
3092  ! loop over edges to fill lookup table
3093  do iedge = 1, this%nedges
3094  n = this%nodedge(iedge)
3095  start = this%iedge_ptr(n)
3096  end = this%iedge_ptr(n + 1) - 1
3097  do ipos = start, end
3098  if (this%edge_idxs(ipos) > 0) cycle ! go to next
3099  this%edge_idxs(ipos) = iedge
3100  exit
3101  end do
3102  end do
3103 

◆ prepcheck()

subroutine gwfnpfmodule::prepcheck ( class(gwfnpftype)  this)

Definition at line 1914 of file gwf-npf.f90.

1915  ! -- modules
1916  use constantsmodule, only: linelength, dpio180
1918  ! -- dummy
1919  class(GwfNpfType) :: this
1920  ! -- local
1921  character(len=24), dimension(:), pointer :: aname
1922  character(len=LINELENGTH) :: cellstr, errmsg
1923  integer(I4B) :: nerr, n
1924  ! -- format
1925  character(len=*), parameter :: fmtkerr = &
1926  &"(1x, 'Hydraulic property ',a,' is <= 0 for cell ',a, ' ', 1pg15.6)"
1927  character(len=*), parameter :: fmtkerr2 = &
1928  &"(1x, '... ', i0,' additional errors not shown for ',a)"
1929  !
1930  ! -- initialize
1931  aname => this%aname
1932  !
1933  ! -- check k11
1934  nerr = 0
1935  do n = 1, size(this%k11)
1936  if (this%k11(n) <= dzero) then
1937  nerr = nerr + 1
1938  if (nerr <= 20) then
1939  call this%dis%noder_to_string(n, cellstr)
1940  write (errmsg, fmtkerr) trim(adjustl(aname(2))), trim(cellstr), &
1941  this%k11(n)
1942  call store_error(errmsg)
1943  end if
1944  end if
1945  end do
1946  if (nerr > 20) then
1947  write (errmsg, fmtkerr2) nerr, trim(adjustl(aname(2)))
1948  call store_error(errmsg)
1949  end if
1950  !
1951  ! -- check k33 because it was read
1952  if (this%ik33 /= 0) then
1953  !
1954  ! -- Check to make sure values are greater than or equal to zero
1955  nerr = 0
1956  do n = 1, size(this%k33)
1957  if (this%ik33overk /= 0) this%k33(n) = this%k33(n) * this%k11(n)
1958  if (this%k33(n) <= dzero) then
1959  nerr = nerr + 1
1960  if (nerr <= 20) then
1961  call this%dis%noder_to_string(n, cellstr)
1962  write (errmsg, fmtkerr) trim(adjustl(aname(3))), trim(cellstr), &
1963  this%k33(n)
1964  call store_error(errmsg)
1965  end if
1966  end if
1967  end do
1968  if (nerr > 20) then
1969  write (errmsg, fmtkerr2) nerr, trim(adjustl(aname(3)))
1970  call store_error(errmsg)
1971  end if
1972  end if
1973  !
1974  ! -- check k22 because it was read
1975  if (this%ik22 /= 0) then
1976  !
1977  ! -- Check to make sure that angles are available
1978  if (this%dis%con%ianglex == 0) then
1979  write (errmsg, '(a)') 'Error. ANGLDEGX not provided in '// &
1980  'discretization file, but K22 was specified. '
1981  call store_error(errmsg)
1982  end if
1983  !
1984  ! -- Check to make sure values are greater than or equal to zero
1985  nerr = 0
1986  do n = 1, size(this%k22)
1987  if (this%ik22overk /= 0) this%k22(n) = this%k22(n) * this%k11(n)
1988  if (this%k22(n) <= dzero) then
1989  nerr = nerr + 1
1990  if (nerr <= 20) then
1991  call this%dis%noder_to_string(n, cellstr)
1992  write (errmsg, fmtkerr) trim(adjustl(aname(4))), trim(cellstr), &
1993  this%k22(n)
1994  call store_error(errmsg)
1995  end if
1996  end if
1997  end do
1998  if (nerr > 20) then
1999  write (errmsg, fmtkerr2) nerr, trim(adjustl(aname(4)))
2000  call store_error(errmsg)
2001  end if
2002  end if
2003  !
2004  ! -- check for wetdry conflicts
2005  if (this%irewet == 1) then
2006  if (this%iwetdry == 0) then
2007  write (errmsg, '(a, a, a)') 'Error in GRIDDATA block: ', &
2008  trim(adjustl(aname(5))), ' not found.'
2009  call store_error(errmsg)
2010  end if
2011  end if
2012  !
2013  ! -- Check for angle conflicts
2014  if (this%iangle1 /= 0) then
2015  do n = 1, size(this%angle1)
2016  this%angle1(n) = this%angle1(n) * dpio180
2017  end do
2018  else
2019  if (this%ixt3d /= 0) then
2020  this%iangle1 = 1
2021  write (this%iout, '(a)') 'XT3D IN USE, BUT ANGLE1 NOT SPECIFIED. '// &
2022  'SETTING ANGLE1 TO ZERO.'
2023  do n = 1, size(this%angle1)
2024  this%angle1(n) = dzero
2025  end do
2026  end if
2027  end if
2028  if (this%iangle2 /= 0) then
2029  if (this%iangle1 == 0) then
2030  write (errmsg, '(a)') 'ANGLE2 SPECIFIED BUT NOT ANGLE1. '// &
2031  'ANGLE2 REQUIRES ANGLE1. '
2032  call store_error(errmsg)
2033  end if
2034  if (this%iangle3 == 0) then
2035  write (errmsg, '(a)') 'ANGLE2 SPECIFIED BUT NOT ANGLE3. '// &
2036  'SPECIFY BOTH OR NEITHER ONE. '
2037  call store_error(errmsg)
2038  end if
2039  do n = 1, size(this%angle2)
2040  this%angle2(n) = this%angle2(n) * dpio180
2041  end do
2042  end if
2043  if (this%iangle3 /= 0) then
2044  if (this%iangle1 == 0) then
2045  write (errmsg, '(a)') 'ANGLE3 SPECIFIED BUT NOT ANGLE1. '// &
2046  'ANGLE3 REQUIRES ANGLE1. '
2047  call store_error(errmsg)
2048  end if
2049  if (this%iangle2 == 0) then
2050  write (errmsg, '(a)') 'ANGLE3 SPECIFIED BUT NOT ANGLE2. '// &
2051  'SPECIFY BOTH OR NEITHER ONE. '
2052  call store_error(errmsg)
2053  end if
2054  do n = 1, size(this%angle3)
2055  this%angle3(n) = this%angle3(n) * dpio180
2056  end do
2057  end if
2058  !
2059  ! -- terminate if data errors
2060  if (count_errors() > 0) then
2061  call store_error_filename(this%input_fname)
2062  end if
real(dp), parameter dpio180
real constant
Definition: Constants.f90:130
Here is the call graph for this function:

◆ preprocess_input()

subroutine gwfnpfmodule::preprocess_input ( class(gwfnpftype)  this)

This routine consists of the following steps:

  1. convert cells to noflow when all transmissive parameters equal zero
  2. perform initial wetting and drying
  3. initialize cell saturation
  4. calculate saturated conductance (when not xt3d)
  5. If NEWTON under-relaxation, determine lower most node
    Parameters
    thisthe instance of the NPF package

Definition at line 2075 of file gwf-npf.f90.

2076  ! -- modules
2077  use constantsmodule, only: linelength
2079  ! -- dummy
2080  class(GwfNpfType) :: this !< the instance of the NPF package
2081  ! -- local
2082  integer(I4B) :: n, m, ii, nn
2083  real(DP) :: hyn, hym
2084  real(DP) :: satn, topn, botn
2085  integer(I4B) :: nextn
2086  real(DP) :: minbot, botm
2087  logical :: finished
2088  character(len=LINELENGTH) :: cellstr, errmsg
2089  ! -- format
2090  character(len=*), parameter :: fmtcnv = &
2091  "(1X,'CELL ', A, &
2092  &' ELIMINATED BECAUSE ALL HYDRAULIC CONDUCTIVITIES TO NODE ARE 0.')"
2093  character(len=*), parameter :: fmtnct = &
2094  &"(1X,'Negative cell thickness at cell ', A)"
2095  character(len=*), parameter :: fmtihbe = &
2096  &"(1X,'Initial head, bottom elevation:',1P,2G13.5)"
2097  character(len=*), parameter :: fmttebe = &
2098  &"(1X,'Top elevation, bottom elevation:',1P,2G13.5)"
2099  !
2100  do n = 1, this%dis%nodes
2101  this%ithickstartflag(n) = 0
2102  end do
2103  !
2104  ! -- Insure that each cell has at least one non-zero transmissive parameter
2105  ! Note that a cell can be deactivated even if it has a valid connection
2106  ! to another model.
2107  nodeloop: do n = 1, this%dis%nodes
2108  !
2109  ! -- Skip if already inactive
2110  if (this%ibound(n) == 0) then
2111  if (this%irewet /= 0) then
2112  if (this%wetdry(n) == dzero) cycle nodeloop
2113  else
2114  cycle nodeloop
2115  end if
2116  end if
2117  !
2118  ! -- Cycle if k11 is not zero
2119  if (this%k11(n) /= dzero) cycle nodeloop
2120  !
2121  ! -- Cycle if at least one vertical connection has non-zero k33
2122  ! for n and m
2123  do ii = this%dis%con%ia(n) + 1, this%dis%con%ia(n + 1) - 1
2124  m = this%dis%con%ja(ii)
2125  if (this%dis%con%ihc(this%dis%con%jas(ii)) == 0) then
2126  hyn = this%k11(n)
2127  if (this%ik33 /= 0) hyn = this%k33(n)
2128  if (hyn /= dzero) then
2129  hym = this%k11(m)
2130  if (this%ik33 /= 0) hym = this%k33(m)
2131  if (hym /= dzero) cycle
2132  end if
2133  end if
2134  end do
2135  !
2136  ! -- If this part of the loop is reached, then all connections have
2137  ! zero transmissivity, so convert to noflow.
2138  this%ibound(n) = 0
2139  this%hnew(n) = this%hnoflo
2140  if (this%irewet /= 0) this%wetdry(n) = dzero
2141  call this%dis%noder_to_string(n, cellstr)
2142  write (this%iout, fmtcnv) trim(adjustl(cellstr))
2143  !
2144  end do nodeloop
2145  !
2146  ! -- Preprocess cell status and heads based on initial conditions
2147  if (this%inewton == 0) then
2148  !
2149  ! -- For standard formulation (non-Newton) call wetdry routine
2150  call this%wd(0, this%hnew)
2151  else
2152  !
2153  ! -- Newton formulation, so adjust heads to be above bottom
2154  ! (Not used in present formulation because variable cv
2155  ! cannot be used with Newton)
2156  if (this%ivarcv == 1) then
2157  do n = 1, this%dis%nodes
2158  if (this%hnew(n) < this%dis%bot(n)) then
2159  this%hnew(n) = this%dis%bot(n) + dem6
2160  end if
2161  end do
2162  end if
2163  end if
2164  !
2165  ! -- If THCKSTRT is not active, then loop through icelltype and replace
2166  ! any negative values with 1.
2167  if (this%ithickstrt == 0) then
2168  do n = 1, this%dis%nodes
2169  if (this%icelltype(n) < 0) then
2170  this%icelltype(n) = 1
2171  end if
2172  end do
2173  end if
2174  !
2175  ! -- Initialize sat to zero for ibound=0 cells, unless the cell can
2176  ! rewet. Initialize sat to the saturated fraction based on strt
2177  ! if icelltype is negative and the THCKSTRT option is in effect.
2178  ! Initialize sat to 1.0 for all other cells in order to calculate
2179  ! condsat in next section.
2180  do n = 1, this%dis%nodes
2181  if (this%ibound(n) == 0) then
2182  this%sat(n) = done
2183  if (this%icelltype(n) < 0 .and. this%ithickstrt /= 0) then
2184  this%ithickstartflag(n) = 1
2185  this%icelltype(n) = 0
2186  end if
2187  else
2188  topn = this%dis%top(n)
2189  botn = this%dis%bot(n)
2190  if (this%icelltype(n) < 0 .and. this%ithickstrt /= 0) then
2191  call this%thksat(n, this%ic%strt(n), satn)
2192  if (botn > this%ic%strt(n)) then
2193  call this%dis%noder_to_string(n, cellstr)
2194  write (errmsg, fmtnct) trim(adjustl(cellstr))
2195  call store_error(errmsg)
2196  write (errmsg, fmtihbe) this%ic%strt(n), botn
2197  call store_error(errmsg)
2198  end if
2199  this%ithickstartflag(n) = 1
2200  this%icelltype(n) = 0
2201  else
2202  satn = done
2203  if (botn > topn) then
2204  call this%dis%noder_to_string(n, cellstr)
2205  write (errmsg, fmtnct) trim(adjustl(cellstr))
2206  call store_error(errmsg)
2207  write (errmsg, fmttebe) topn, botn
2208  call store_error(errmsg)
2209  end if
2210  end if
2211  this%sat(n) = satn
2212  end if
2213  end do
2214  if (count_errors() > 0) then
2215  call store_error_filename(this%input_fname)
2216  end if
2217  !
2218  ! -- Calculate condsat, but only if xt3d is not active. If xt3d is
2219  ! active, then condsat is allocated to size of zero.
2220  if (this%ixt3d == 0) then
2221  !
2222  ! -- Calculate the saturated conductance for all connections assuming
2223  ! that saturation is 1 (except for case where icelltype was entered
2224  ! as a negative value and THCKSTRT option in effect)
2225  do n = 1, this%dis%nodes
2226  call this%calc_condsat(n, .true.)
2227  end do
2228  !
2229  end if
2230  !
2231  ! -- Determine the lower most node
2232  if (this%igwfnewtonur /= 0) then
2233  call mem_reallocate(this%ibotnode, this%dis%nodes, 'IBOTNODE', &
2234  trim(this%memoryPath))
2235  do n = 1, this%dis%nodes
2236  !
2237  minbot = this%dis%bot(n)
2238  nn = n
2239  finished = .false.
2240  do while (.not. finished)
2241  nextn = 0
2242  !
2243  ! -- Go through the connecting cells
2244  do ii = this%dis%con%ia(nn) + 1, this%dis%con%ia(nn + 1) - 1
2245  !
2246  ! -- Set the m cell number
2247  m = this%dis%con%ja(ii)
2248  botm = this%dis%bot(m)
2249  !
2250  ! -- select vertical connections: ihc == 0
2251  if (this%dis%con%ihc(this%dis%con%jas(ii)) == 0) then
2252  if (m > nn .and. botm < minbot) then
2253  nextn = m
2254  minbot = botm
2255  end if
2256  end if
2257  end do
2258  if (nextn > 0) then
2259  nn = nextn
2260  else
2261  finished = .true.
2262  end if
2263  end do
2264  this%ibotnode(n) = nn
2265  end do
2266  end if
2267  !
2268  ! -- nullify unneeded gwf pointers
2269  this%igwfnewtonur => null()
Here is the call graph for this function:

◆ rewet_check()

subroutine gwfnpfmodule::rewet_check ( class(gwfnpftype)  this,
integer(i4b), intent(in)  kiter,
integer(i4b), intent(in)  node,
real(dp), intent(in)  hm,
integer(i4b), intent(in)  ibdm,
integer(i4b), intent(in)  ihc,
real(dp), dimension(:), intent(inout)  hnew,
integer(i4b), intent(out)  irewet 
)

This method can be called from any external object that has a head that can be used to rewet the GWF cell node. The ihc value is used to determine if it is a vertical or horizontal connection, which can operate differently depending on user settings.

Definition at line 2494 of file gwf-npf.f90.

2495  ! -- dummy
2496  class(GwfNpfType) :: this
2497  integer(I4B), intent(in) :: kiter
2498  integer(I4B), intent(in) :: node
2499  real(DP), intent(in) :: hm
2500  integer(I4B), intent(in) :: ibdm
2501  integer(I4B), intent(in) :: ihc
2502  real(DP), intent(inout), dimension(:) :: hnew
2503  integer(I4B), intent(out) :: irewet
2504  ! -- local
2505  integer(I4B) :: itflg
2506  real(DP) :: wd, awd, turnon, bbot
2507  !
2508  irewet = 0
2509  !
2510  ! -- Convert a dry cell to wet if it meets the criteria
2511  if (this%irewet > 0) then
2512  itflg = mod(kiter, this%iwetit)
2513  if (itflg == 0) then
2514  if (this%ibound(node) == 0 .and. this%wetdry(node) /= dzero) then
2515  !
2516  ! -- Calculate wetting elevation
2517  bbot = this%dis%bot(node)
2518  wd = this%wetdry(node)
2519  awd = wd
2520  if (wd < 0) awd = -wd
2521  turnon = bbot + awd
2522  !
2523  ! -- Check head in adjacent cells to see if wetting elevation has
2524  ! been reached
2525  if (ihc == c3d_vertical) then
2526  !
2527  ! -- check cell below
2528  if (ibdm > 0 .and. hm >= turnon) irewet = 1
2529  else
2530  if (wd > dzero) then
2531  !
2532  ! -- check horizontally adjacent cells
2533  if (ibdm > 0 .and. hm >= turnon) irewet = 1
2534  end if
2535  end if
2536  !
2537  if (irewet == 1) then
2538  ! -- rewet cell; use equation 3a if ihdwet=0; use equation 3b if
2539  ! ihdwet is not 0.
2540  if (this%ihdwet == 0) then
2541  hnew(node) = bbot + this%wetfct * (hm - bbot)
2542  else
2543  hnew(node) = bbot + this%wetfct * awd !(hm - bbot)
2544  end if
2545  this%ibound(node) = 30000
2546  end if
2547  end if
2548  end if
2549  end if

◆ sav_sat()

subroutine gwfnpfmodule::sav_sat ( class(gwfnpftype)  this,
integer(i4b), intent(in)  ibinun 
)
private

Definition at line 2965 of file gwf-npf.f90.

2966  ! -- dummy
2967  class(GwfNpfType) :: this
2968  integer(I4B), intent(in) :: ibinun
2969  ! -- local
2970  character(len=16) :: text
2971  character(len=16), dimension(1) :: auxtxt
2972  real(DP), dimension(1) :: a
2973  integer(I4B) :: n
2974  integer(I4B) :: naux
2975  !
2976  ! -- Write the header
2977  text = ' DATA-SAT'
2978  naux = 1
2979  auxtxt(:) = [' sat']
2980  call this%dis%record_srcdst_list_header(text, this%name_model, &
2981  this%packName, this%name_model, &
2982  this%packName, naux, auxtxt, ibinun, &
2983  this%dis%nodes, this%iout)
2984  !
2985  ! -- Write a zero for Q, and then write saturation as an aux variables
2986  do n = 1, this%dis%nodes
2987  a(1) = this%sat(n)
2988  call this%dis%record_mf6_list_entry(ibinun, n, n, dzero, naux, a)
2989  end do

◆ sav_spdis()

subroutine gwfnpfmodule::sav_spdis ( class(gwfnpftype)  this,
integer(i4b), intent(in)  ibinun 
)

Definition at line 2937 of file gwf-npf.f90.

2938  ! -- dummy
2939  class(GwfNpfType) :: this
2940  integer(I4B), intent(in) :: ibinun
2941  ! -- local
2942  character(len=16) :: text
2943  character(len=16), dimension(3) :: auxtxt
2944  integer(I4B) :: n
2945  integer(I4B) :: naux
2946  !
2947  ! -- Write the header
2948  text = ' DATA-SPDIS'
2949  naux = 3
2950  auxtxt(:) = [' qx', ' qy', ' qz']
2951  call this%dis%record_srcdst_list_header(text, this%name_model, &
2952  this%packName, this%name_model, &
2953  this%packName, naux, auxtxt, ibinun, &
2954  this%dis%nodes, this%iout)
2955  !
2956  ! -- Write a zero for Q, and then write qx, qy, qz as aux variables
2957  do n = 1, this%dis%nodes
2958  call this%dis%record_mf6_list_entry(ibinun, n, n, dzero, naux, &
2959  this%spdis(:, n))
2960  end do

◆ set_edge_properties()

subroutine gwfnpfmodule::set_edge_properties ( class(gwfnpftype)  this,
integer(i4b), intent(in)  nodedge,
integer(i4b), intent(in)  ihcedge,
real(dp), intent(in)  q,
real(dp), intent(in)  area,
real(dp), intent(in)  nx,
real(dp), intent(in)  ny,
real(dp), intent(in)  distance 
)
private

Definition at line 3034 of file gwf-npf.f90.

3036  ! -- dummy
3037  class(GwfNpfType) :: this
3038  integer(I4B), intent(in) :: nodedge
3039  integer(I4B), intent(in) :: ihcedge
3040  real(DP), intent(in) :: q
3041  real(DP), intent(in) :: area
3042  real(DP), intent(in) :: nx
3043  real(DP), intent(in) :: ny
3044  real(DP), intent(in) :: distance
3045  ! -- local
3046  integer(I4B) :: lastedge
3047  !
3048  this%lastedge = this%lastedge + 1
3049  lastedge = this%lastedge
3050  this%nodedge(lastedge) = nodedge
3051  this%ihcedge(lastedge) = ihcedge
3052  this%propsedge(1, lastedge) = q
3053  this%propsedge(2, lastedge) = area
3054  this%propsedge(3, lastedge) = nx
3055  this%propsedge(4, lastedge) = ny
3056  this%propsedge(5, lastedge) = distance
3057  !
3058  ! -- If this is the last edge, then the next call must be starting a new
3059  ! edge properties assignment loop, so need to reset lastedge to 0
3060  if (this%lastedge == this%nedges) this%lastedge = 0

◆ set_options()

subroutine gwfnpfmodule::set_options ( class(gwfnpftype)  this,
type(gwfnpfoptionstype), intent(in)  options 
)

Definition at line 1680 of file gwf-npf.f90.

1681  ! -- dummy
1682  class(GwfNpftype) :: this
1683  type(GwfNpfOptionsType), intent(in) :: options
1684  !
1685  this%ithickstrt = options%ithickstrt
1686  this%ihighcellsat = options%ihighcellsat
1687  this%iperched = options%iperched
1688  this%ivarcv = options%ivarcv
1689  this%idewatcv = options%idewatcv
1690  this%irewet = options%irewet
1691  this%wetfct = options%wetfct
1692  this%iwetit = options%iwetit
1693  this%ihdwet = options%ihdwet

◆ sgwf_npf_qcalc()

subroutine gwfnpfmodule::sgwf_npf_qcalc ( class(gwfnpftype)  this,
integer(i4b), intent(in)  n,
integer(i4b), intent(in)  m,
real(dp), intent(in)  hn,
real(dp), intent(in)  hm,
integer(i4b), intent(in)  icon,
real(dp), intent(inout)  qnm 
)
private

Definition at line 1056 of file gwf-npf.f90.

1057  ! -- dummy
1058  class(GwfNpfType) :: this
1059  integer(I4B), intent(in) :: n
1060  integer(I4B), intent(in) :: m
1061  real(DP), intent(in) :: hn
1062  real(DP), intent(in) :: hm
1063  integer(I4B), intent(in) :: icon
1064  real(DP), intent(inout) :: qnm
1065  ! -- local
1066  real(DP) :: hyn, hym
1067  real(DP) :: condnm
1068  real(DP) :: hntemp, hmtemp
1069  real(DP) :: satn, satm
1070  integer(I4B) :: ihc
1071  !
1072  ! -- Initialize
1073  ihc = this%dis%con%ihc(this%dis%con%jas(icon))
1074  hyn = this%hy_eff(n, m, ihc, ipos=icon)
1075  hym = this%hy_eff(m, n, ihc, ipos=icon)
1076  !
1077  ! -- Calculate conductance
1078  if (ihc == c3d_vertical) then
1079  condnm = vcond(this%ibound(n), this%ibound(m), &
1080  this%icelltype(n), this%icelltype(m), this%inewton, &
1081  this%ivarcv, this%idewatcv, &
1082  this%condsat(this%dis%con%jas(icon)), hn, hm, &
1083  hyn, hym, &
1084  this%sat(n), this%sat(m), &
1085  this%dis%top(n), this%dis%top(m), &
1086  this%dis%bot(n), this%dis%bot(m), &
1087  this%dis%con%hwva(this%dis%con%jas(icon)))
1088  else
1089  satn = this%sat(n)
1090  satm = this%sat(m)
1091  if (this%ihighcellsat /= 0) then
1092  call this%highest_cell_saturation(n, m, hn, hm, satn, satm)
1093  end if
1094 
1095  condnm = hcond(this%ibound(n), this%ibound(m), &
1096  this%icelltype(n), this%icelltype(m), &
1097  this%inewton, &
1098  this%dis%con%ihc(this%dis%con%jas(icon)), &
1099  this%icellavg, &
1100  this%condsat(this%dis%con%jas(icon)), &
1101  hn, hm, satn, satm, hyn, hym, &
1102  this%dis%top(n), this%dis%top(m), &
1103  this%dis%bot(n), this%dis%bot(m), &
1104  this%dis%con%cl1(this%dis%con%jas(icon)), &
1105  this%dis%con%cl2(this%dis%con%jas(icon)), &
1106  this%dis%con%hwva(this%dis%con%jas(icon)))
1107  end if
1108  !
1109  ! -- Initialize hntemp and hmtemp
1110  hntemp = hn
1111  hmtemp = hm
1112  !
1113  ! -- Check and adjust for dewatered conditions
1114  if (this%iperched /= 0) then
1115  if (this%dis%con%ihc(this%dis%con%jas(icon)) == 0) then
1116  if (n > m) then
1117  if (this%icelltype(n) /= 0) then
1118  if (hn < this%dis%top(n)) hntemp = this%dis%bot(m)
1119  end if
1120  else
1121  if (this%icelltype(m) /= 0) then
1122  if (hm < this%dis%top(m)) hmtemp = this%dis%bot(n)
1123  end if
1124  end if
1125  end if
1126  end if
1127  !
1128  ! -- Calculate flow positive into cell n
1129  qnm = condnm * (hmtemp - hntemp)
Here is the call graph for this function:

◆ sgwf_npf_thksat()

subroutine gwfnpfmodule::sgwf_npf_thksat ( class(gwfnpftype)  this,
integer(i4b), intent(in)  n,
real(dp), intent(in)  hn,
real(dp), intent(inout)  thksat 
)
private

Definition at line 1033 of file gwf-npf.f90.

1034  ! -- dummy
1035  class(GwfNpfType) :: this
1036  integer(I4B), intent(in) :: n
1037  real(DP), intent(in) :: hn
1038  real(DP), intent(inout) :: thksat
1039  !
1040  ! -- Standard Formulation
1041  if (hn >= this%dis%top(n)) then
1042  thksat = done
1043  else
1044  thksat = (hn - this%dis%bot(n)) / (this%dis%top(n) - this%dis%bot(n))
1045  end if
1046  !
1047  ! -- Newton-Raphson Formulation
1048  if (this%inewton /= 0) then
1049  thksat = squadraticsaturation(this%dis%top(n), this%dis%bot(n), hn, &
1050  this%satomega)
1051  end if
Here is the call graph for this function:

◆ sgwf_npf_wdmsg()

subroutine gwfnpfmodule::sgwf_npf_wdmsg ( class(gwfnpftype)  this,
integer(i4b), intent(in)  icode,
integer(i4b), intent(inout)  ncnvrt,
character(len=30), dimension(5), intent(inout)  nodcnvrt,
character(len=3), dimension(5), intent(inout)  acnvrt,
integer(i4b), intent(inout)  ihdcnv,
integer(i4b), intent(in)  kiter,
integer(i4b), intent(in)  n 
)
private

Definition at line 2554 of file gwf-npf.f90.

2556  ! -- modules
2557  use tdismodule, only: kstp, kper
2558  ! -- dummy
2559  class(GwfNpfType) :: this
2560  integer(I4B), intent(in) :: icode
2561  integer(I4B), intent(inout) :: ncnvrt
2562  character(len=30), dimension(5), intent(inout) :: nodcnvrt
2563  character(len=3), dimension(5), intent(inout) :: acnvrt
2564  integer(I4B), intent(inout) :: ihdcnv
2565  integer(I4B), intent(in) :: kiter
2566  integer(I4B), intent(in) :: n
2567  ! -- local
2568  integer(I4B) :: l
2569  ! -- formats
2570  character(len=*), parameter :: fmtcnvtn = &
2571  "(1X,/1X,'CELL CONVERSIONS FOR ITER.=',I0, &
2572  &' STEP=',I0,' PERIOD=',I0,' (NODE or LRC)')"
2573  character(len=*), parameter :: fmtnode = "(1X,3X,5(A4, A20))"
2574  !
2575  ! -- Keep track of cell conversions
2576  if (icode > 0) then
2577  ncnvrt = ncnvrt + 1
2578  call this%dis%noder_to_string(n, nodcnvrt(ncnvrt))
2579  if (icode == 1) then
2580  acnvrt(ncnvrt) = 'DRY'
2581  else
2582  acnvrt(ncnvrt) = 'WET'
2583  end if
2584  end if
2585  !
2586  ! -- Print a line if 5 conversions have occurred or if icode indicates that a
2587  ! partial line should be printed
2588  if (ncnvrt == 5 .or. (icode == 0 .and. ncnvrt > 0)) then
2589  if (ihdcnv == 0) write (this%iout, fmtcnvtn) kiter, kstp, kper
2590  ihdcnv = 1
2591  write (this%iout, fmtnode) &
2592  (acnvrt(l), trim(adjustl(nodcnvrt(l))), l=1, ncnvrt)
2593  ncnvrt = 0
2594  end if

◆ sgwf_npf_wetdry()

subroutine gwfnpfmodule::sgwf_npf_wetdry ( class(gwfnpftype)  this,
integer(i4b), intent(in)  kiter,
real(dp), dimension(:), intent(inout)  hnew 
)
private

Definition at line 2388 of file gwf-npf.f90.

2389  ! -- modules
2390  use tdismodule, only: kstp, kper
2392  use constantsmodule, only: linelength
2393  ! -- dummy
2394  class(GwfNpfType) :: this
2395  integer(I4B), intent(in) :: kiter
2396  real(DP), intent(inout), dimension(:) :: hnew
2397  ! -- local
2398  integer(I4B) :: n, m, ii, ihc
2399  real(DP) :: ttop, bbot, thick
2400  integer(I4B) :: ncnvrt, ihdcnv
2401  character(len=30), dimension(5) :: nodcnvrt
2402  character(len=30) :: nodestr
2403  character(len=3), dimension(5) :: acnvrt
2404  character(len=LINELENGTH) :: errmsg
2405  integer(I4B) :: irewet
2406  ! -- formats
2407  character(len=*), parameter :: fmtnct = &
2408  "(1X,/1X,'Negative cell thickness at (layer,row,col)', &
2409  &I4,',',I5,',',I5)"
2410  character(len=*), parameter :: fmttopbot = &
2411  &"(1X,'Top elevation, bottom elevation:',1P,2G13.5)"
2412  character(len=*), parameter :: fmttopbotthk = &
2413  &"(1X,'Top elevation, bottom elevation, thickness:',1P,3G13.5)"
2414  character(len=*), parameter :: fmtdrychd = &
2415  &"(1X,/1X,'CONSTANT-HEAD CELL WENT DRY -- SIMULATION ABORTED')"
2416  character(len=*), parameter :: fmtni = &
2417  &"(1X,'CELLID=',a,' ITERATION=',I0,' TIME STEP=',I0,' STRESS PERIOD=',I0)"
2418  !
2419  ! -- Initialize
2420  ncnvrt = 0
2421  ihdcnv = 0
2422  !
2423  ! -- Convert dry cells to wet
2424  do n = 1, this%dis%nodes
2425  do ii = this%dis%con%ia(n) + 1, this%dis%con%ia(n + 1) - 1
2426  m = this%dis%con%ja(ii)
2427  ihc = this%dis%con%ihc(this%dis%con%jas(ii))
2428  call this%rewet_check(kiter, n, hnew(m), this%ibound(m), ihc, hnew, &
2429  irewet)
2430  if (irewet == 1) then
2431  call this%wdmsg(2, ncnvrt, nodcnvrt, acnvrt, ihdcnv, kiter, n)
2432  end if
2433  end do
2434  end do
2435  !
2436  ! -- Perform drying
2437  do n = 1, this%dis%nodes
2438  !
2439  ! -- cycle if inactive or confined
2440  if (this%ibound(n) == 0) cycle
2441  if (this%icelltype(n) == 0) cycle
2442  !
2443  ! -- check for negative cell thickness
2444  bbot = this%dis%bot(n)
2445  ttop = this%dis%top(n)
2446  if (bbot > ttop) then
2447  write (errmsg, fmtnct) n
2448  call store_error(errmsg)
2449  write (errmsg, fmttopbot) ttop, bbot
2450  call store_error(errmsg)
2451  call store_error_filename(this%input_fname)
2452  end if
2453  !
2454  ! -- Calculate saturated thickness
2455  if (this%icelltype(n) /= 0) then
2456  if (hnew(n) < ttop) ttop = hnew(n)
2457  end if
2458  thick = ttop - bbot
2459  !
2460  ! -- If thick<0 print message, set hnew, and ibound
2461  if (thick <= dzero) then
2462  call this%wdmsg(1, ncnvrt, nodcnvrt, acnvrt, ihdcnv, kiter, n)
2463  hnew(n) = this%hdry
2464  if (this%ibound(n) < 0) then
2465  errmsg = 'CONSTANT-HEAD CELL WENT DRY -- SIMULATION ABORTED'
2466  call store_error(errmsg)
2467  write (errmsg, fmttopbotthk) ttop, bbot, thick
2468  call store_error(errmsg)
2469  call this%dis%noder_to_string(n, nodestr)
2470  write (errmsg, fmtni) trim(adjustl(nodestr)), kiter, kstp, kper
2471  call store_error(errmsg)
2472  call store_error_filename(this%input_fname)
2473  end if
2474  this%ibound(n) = 0
2475  end if
2476  end do
2477  !
2478  ! -- Print remaining cell conversions
2479  call this%wdmsg(0, ncnvrt, nodcnvrt, acnvrt, ihdcnv, kiter, n)
2480  !
2481  ! -- Change ibound from 30000 to 1
2482  do n = 1, this%dis%nodes
2483  if (this%ibound(n) == 30000) this%ibound(n) = 1
2484  end do
Here is the call graph for this function:

◆ source_griddata()

subroutine gwfnpfmodule::source_griddata ( class(gwfnpftype)  this)

Definition at line 1819 of file gwf-npf.f90.

1820  ! -- modules
1821  use simmodule, only: count_errors, store_error
1825  ! -- dummy
1826  class(GwfNpftype) :: this
1827  ! -- locals
1828  character(len=LINELENGTH) :: errmsg
1829  type(GwfNpfParamFoundType) :: found
1830  logical, dimension(2) :: afound
1831  integer(I4B), dimension(:), pointer, contiguous :: map
1832  !
1833  ! -- set map to convert user input data into reduced data
1834  map => null()
1835  if (this%dis%nodes < this%dis%nodesuser) map => this%dis%nodeuser
1836  !
1837  ! -- update defaults with idm sourced values
1838  call mem_set_value(this%icelltype, 'ICELLTYPE', this%input_mempath, map, &
1839  found%icelltype)
1840  call mem_set_value(this%k11, 'K', this%input_mempath, map, found%k, &
1841  release=.false.)
1842  call mem_set_value(this%k33, 'K33', this%input_mempath, map, found%k33)
1843  call mem_set_value(this%k22, 'K22', this%input_mempath, map, found%k22)
1844  call mem_set_value(this%wetdry, 'WETDRY', this%input_mempath, map, &
1845  found%wetdry)
1846  call mem_set_value(this%angle1, 'ANGLE1', this%input_mempath, map, &
1847  found%angle1)
1848  call mem_set_value(this%angle2, 'ANGLE2', this%input_mempath, map, &
1849  found%angle2)
1850  call mem_set_value(this%angle3, 'ANGLE3', this%input_mempath, map, &
1851  found%angle3)
1852  !
1853  ! -- ensure ICELLTYPE was found
1854  if (.not. found%icelltype) then
1855  write (errmsg, '(a)') 'Error in GRIDDATA block: ICELLTYPE not found.'
1856  call store_error(errmsg)
1857  end if
1858  !
1859  ! -- ensure K was found
1860  if (.not. found%k) then
1861  write (errmsg, '(a)') 'Error in GRIDDATA block: K not found.'
1862  call store_error(errmsg)
1863  end if
1864  !
1865  ! -- set error if ik33overk set with no k33
1866  if (.not. found%k33 .and. this%ik33overk /= 0) then
1867  write (errmsg, '(a)') 'K33OVERK option specified but K33 not specified.'
1868  call store_error(errmsg)
1869  end if
1870  !
1871  ! -- set error if ik22overk set with no k22
1872  if (.not. found%k22 .and. this%ik22overk /= 0) then
1873  write (errmsg, '(a)') 'K22OVERK option specified but K22 not specified.'
1874  call store_error(errmsg)
1875  end if
1876  !
1877  ! -- handle found side effects
1878  if (found%k33) this%ik33 = 1
1879  if (found%k22) this%ik22 = 1
1880  if (found%wetdry) this%iwetdry = 1
1881  if (found%angle1) this%iangle1 = 1
1882  if (found%angle2) this%iangle2 = 1
1883  if (found%angle3) this%iangle3 = 1
1884  !
1885  ! -- handle not found side effects
1886  if (.not. found%k33) then
1887  call mem_set_value(this%k33, 'K', this%input_mempath, map, afound(1), &
1888  release=.false.)
1889  end if
1890  if (.not. found%k22) then
1891  call mem_set_value(this%k22, 'K', this%input_mempath, map, afound(2), &
1892  release=.false.)
1893  end if
1894  if (.not. found%wetdry) call mem_reallocate(this%wetdry, 1, 'WETDRY', &
1895  trim(this%memoryPath))
1896  if (.not. found%angle1 .and. this%ixt3d == 0) &
1897  call mem_reallocate(this%angle1, 0, 'ANGLE1', trim(this%memoryPath))
1898  if (.not. found%angle2 .and. this%ixt3d == 0) &
1899  call mem_reallocate(this%angle2, 0, 'ANGLE2', trim(this%memoryPath))
1900  if (.not. found%angle3 .and. this%ixt3d == 0) &
1901  call mem_reallocate(this%angle3, 0, 'ANGLE3', trim(this%memoryPath))
1902  !
1903  ! -- cleanup
1904  call memorystore_release('K', this%input_mempath)
1905  !
1906  ! -- log griddata
1907  if (this%iout > 0) then
1908  call this%log_griddata(found)
1909  end if
subroutine, public memorystore_release(varname, memory_path)
Release a single variable from the memory store.
Here is the call graph for this function:

◆ source_options()

subroutine gwfnpfmodule::source_options ( class(gwfnpftype)  this)

Definition at line 1589 of file gwf-npf.f90.

1590  ! -- modules
1595  use sourcecommonmodule, only: filein_fname
1597  ! -- dummy
1598  class(GwfNpftype) :: this
1599  ! -- locals
1600  character(len=LENVARNAME), dimension(3) :: cellavg_method = &
1601  &[character(len=LENVARNAME) :: 'LOGARITHMIC', 'AMT-LMK', 'AMT-HMK']
1602  type(gwfnpfparamfoundtype) :: found
1603  type(CharacterStringType), dimension(:), pointer, contiguous :: tvk6_mempaths
1604  character(len=LINELENGTH) :: tvk6_filename
1605  character(len=LENMEMPATH) :: tvk6_mempath
1606  !
1607  ! -- update defaults with idm sourced values
1608  call mem_set_value(this%iprflow, 'IPRFLOW', this%input_mempath, found%iprflow)
1609  call mem_set_value(this%ipakcb, 'IPAKCB', this%input_mempath, found%ipakcb)
1610  call mem_set_value(this%icellavg, 'CELLAVG', this%input_mempath, &
1611  cellavg_method, found%cellavg)
1612  call mem_set_value(this%ithickstrt, 'ITHICKSTRT', this%input_mempath, &
1613  found%ithickstrt)
1614  call mem_set_value(this%ihighcellsat, 'IHIGHCELLSAT', this%input_mempath, &
1615  found%ihighcellsat)
1616  call mem_set_value(this%iperched, 'IPERCHED', this%input_mempath, &
1617  found%iperched)
1618  call mem_set_value(this%ivarcv, 'IVARCV', this%input_mempath, found%ivarcv)
1619  call mem_set_value(this%idewatcv, 'IDEWATCV', this%input_mempath, &
1620  found%idewatcv)
1621  call mem_set_value(this%ixt3d, 'IXT3D', this%input_mempath, found%ixt3d)
1622  call mem_set_value(this%ixt3drhs, 'IXT3DRHS', this%input_mempath, &
1623  found%ixt3drhs)
1624  call mem_set_value(this%isavspdis, 'ISAVSPDIS', this%input_mempath, &
1625  found%isavspdis)
1626  call mem_set_value(this%isavsat, 'ISAVSAT', this%input_mempath, found%isavsat)
1627  call mem_set_value(this%ik22overk, 'IK22OVERK', this%input_mempath, &
1628  found%ik22overk)
1629  call mem_set_value(this%ik33overk, 'IK33OVERK', this%input_mempath, &
1630  found%ik33overk)
1631  call mem_set_value(this%inewton, 'INEWTON', this%input_mempath, found%inewton)
1632  call mem_set_value(this%satomega, 'SATOMEGA', this%input_mempath, &
1633  found%satomega)
1634  call mem_set_value(this%irewet, 'IREWET', this%input_mempath, found%irewet)
1635  call mem_set_value(this%wetfct, 'WETFCT', this%input_mempath, found%wetfct)
1636  call mem_set_value(this%iwetit, 'IWETIT', this%input_mempath, found%iwetit)
1637  call mem_set_value(this%ihdwet, 'IHDWET', this%input_mempath, found%ihdwet)
1638  !
1639  ! -- save flows option active
1640  if (found%ipakcb) this%ipakcb = -1
1641  !
1642  ! -- xt3d active with rhs
1643  if (found%ixt3d .and. found%ixt3drhs) this%ixt3d = 2
1644  !
1645  ! -- save specific discharge active
1646  if (found%isavspdis) this%icalcspdis = this%isavspdis
1647  !
1648  ! -- no newton specified
1649  if (found%inewton) then
1650  this%inewton = 0
1651  this%iasym = 0
1652  end if
1653  !
1654  ! -- TVK6 subpackage
1655  if (filein_fname(tvk6_filename, 'TVK6_FILENAME', &
1656  this%input_mempath, this%input_fname)) then
1657  call mem_setptr(tvk6_mempaths, 'TVK6_MEMPATH', this%input_mempath)
1658  tvk6_mempath = tvk6_mempaths(1)
1659  this%intvk = 1 ! tvk active
1660  call tvk_cr(this%tvk, this%name_model, tvk6_mempath, this%intvk, this%iout)
1661  end if
1662  !
1663  ! -- verify ALTERNATIVE_CELL_AVERAGING input value is supported
1664  if (found%cellavg) then
1665  if (this%icellavg == 0) then
1666  errmsg = 'Unrecognized input value for ALTERNATIVE_CELL_AVERAGING option.'
1667  call store_error(errmsg)
1668  call store_error_filename(this%input_fname)
1669  end if
1670  end if
1671  !
1672  ! -- log options
1673  if (this%iout > 0) then
1674  call this%log_options(found)
1675  end if
subroutine, public get_isize(name, mem_path, isize)
@ brief Get the number of elements for this variable
This module contains the SourceCommonModule.
Definition: SourceCommon.f90:7
logical(lgp) function, public filein_fname(filename, tagname, input_mempath, input_fname)
enforce and set a single input filename provided via FILEIN keyword
This class is used to store a single deferred-length character string. It was designed to work in an ...
Definition: CharString.f90:23
Here is the call graph for this function:

◆ store_original_k_arrays()

subroutine gwfnpfmodule::store_original_k_arrays ( class(gwfnpftype)  this,
integer(i4b), intent(in)  ncells,
integer(i4b), intent(in)  njas 
)

The K arrays (K11, etc.) get multiplied by the viscosity ratio so that subsequent uses of K already take into account the effect of viscosity. Thus the original user-specified K array values are lost unless they are backed up in k11input, for example. In a new stress period/time step, the values in k11input are multiplied by the viscosity ratio, not k11 since it contains viscosity-adjusted hydraulic conductivity values.

Definition at line 1417 of file gwf-npf.f90.

1418  ! -- modules
1420  ! -- dummy
1421  class(GwfNpftype) :: this
1422  integer(I4B), intent(in) :: ncells
1423  integer(I4B), intent(in) :: njas
1424  ! -- local
1425  integer(I4B) :: n
1426  !
1427  ! -- Retain copy of user-specified K arrays
1428  do n = 1, ncells
1429  this%k11input(n) = this%k11(n)
1430  this%k22input(n) = this%k22(n)
1431  this%k33input(n) = this%k33(n)
1432  end do