40 character(len=LENFTYPE),
pointer :: swf_ftype => null()
41 character(len=LINELENGTH),
pointer :: filename => null()
42 integer(I4B),
pointer :: ipr_input => null()
43 integer(I4B),
pointer :: ipr_flow => null()
45 integer(I4B),
pointer :: ifixedcond => null()
47 integer(I4B),
pointer :: nexg => null()
48 integer(I4B),
dimension(:),
pointer,
contiguous :: nodeswf => null()
49 integer(I4B),
dimension(:),
pointer,
contiguous :: nodegwf => null()
50 real(dp),
dimension(:),
pointer,
contiguous :: bedleak => null()
51 real(dp),
dimension(:),
pointer,
contiguous :: cfact => null()
52 integer(I4B),
dimension(:),
pointer,
contiguous :: idxglo => null()
53 integer(I4B),
dimension(:),
pointer,
contiguous :: idxsymglo => null()
54 real(dp),
dimension(:),
pointer,
contiguous :: simvals => null()
56 integer(I4B),
pointer :: inobs => null()
96 subroutine initialize(this, filename, name, swf_ftype, id, m1_id, m2_id, &
100 character(len=*),
intent(in) :: filename
101 character(len=*) :: name
102 character(len=*) :: swf_ftype
103 integer(I4B),
intent(in) :: id
104 integer(I4B),
intent(in) :: m1_id
105 integer(I4B),
intent(in) :: m2_id
106 character(len=*),
intent(in) :: input_mempath
109 integer(I4B) :: m1_index, m2_index
115 this%input_mempath = input_mempath
118 call this%allocate_scalars()
119 this%filename = filename
120 this%swf_ftype = swf_ftype
121 this%typename = trim(swf_ftype)//
'-GWF'
125 if (m1_index > 0)
then
138 if (m2_index > 0)
then
149 if (.not.
associated(this%swfmodel) .and. m1_index > 0)
then
152 trim(this%typename), &
156 trim(this%swf_ftype), &
157 ' model does not appear to be of the correct type.'
162 if (.not.
associated(this%gwfmodel) .and. m2_index > 0)
then
163 write (
errmsg,
'(3a)')
'Problem with SWF-GWF exchange ', &
165 '. Specified GWF model does not appear to be of the correct type.'
170 call obs_cr(this%obs, this%inobs)
185 integer(I4B) :: n, iglo, jglo
189 iglo = this%nodeswf(n) + this%swfmodel%moffset
190 jglo = this%nodegwf(n) + this%gwfmodel%moffset
191 call sparse%addconnection(iglo, jglo, 1)
192 call sparse%addconnection(jglo, iglo, 1)
207 integer(I4B) :: n, iglo, jglo
211 iglo = this%nodeswf(n) + this%swfmodel%moffset
212 jglo = this%nodegwf(n) + this%gwfmodel%moffset
213 this%idxglo(n) = matrix_sln%get_position(iglo, jglo)
214 this%idxsymglo(n) = matrix_sln%get_position(jglo, iglo)
224 subroutine swf_gwf_fc(this, kiter, matrix_sln, rhs_sln, inwtflag)
229 integer(I4B),
intent(in) :: kiter
231 real(DP),
dimension(:),
intent(inout) :: rhs_sln
232 integer(I4B),
optional,
intent(in) :: inwtflag
235 integer(I4B) :: nodeswf
236 integer(I4B) :: nodegwf
237 integer(I4B) :: nodeswf_sln
238 integer(I4B) :: nodegwf_sln
239 integer(I4B) :: ibdn1
240 integer(I4B) :: ibdn2
249 do iexg = 1, this%nexg
251 nodeswf = this%nodeswf(iexg)
252 nodegwf = this%nodegwf(iexg)
253 nodeswf_sln = this%nodeswf(iexg) + this%swfmodel%moffset
254 nodegwf_sln = this%nodegwf(iexg) + this%gwfmodel%moffset
255 ibdn1 = this%swfmodel%ibound(nodeswf)
256 ibdn2 = this%gwfmodel%ibound(nodegwf)
257 hswf = this%swfmodel%x(nodeswf)
258 hgwf = this%gwfmodel%x(nodegwf)
263 qnm = this%qcalc(iexg, hswf, hgwf)
264 rhs_sln(nodeswf_sln) = rhs_sln(nodeswf_sln) - qnm
268 qeps = this%qcalc(iexg, hswf + eps, hgwf)
269 derv = (qeps - qnm) / eps
270 call matrix_sln%add_diag_value(nodeswf_sln, derv)
271 rhs_sln(nodeswf_sln) = rhs_sln(nodeswf_sln) + derv * hswf
275 qeps = this%qcalc(iexg, hswf, hgwf + eps)
276 derv = (qeps - qnm) / eps
277 call matrix_sln%add_value_pos(this%idxglo(iexg), derv)
278 rhs_sln(nodeswf_sln) = rhs_sln(nodeswf_sln) + derv * hgwf
283 qnm = -this%qcalc(iexg, hswf, hgwf)
284 rhs_sln(nodegwf_sln) = rhs_sln(nodegwf_sln) - qnm
288 qeps = -this%qcalc(iexg, hswf, hgwf + eps)
289 derv = (qeps - qnm) / eps
290 call matrix_sln%add_diag_value(nodegwf_sln, derv)
291 rhs_sln(nodegwf_sln) = rhs_sln(nodegwf_sln) + derv * hgwf
295 qeps = -this%qcalc(iexg, hswf + eps, hgwf)
296 derv = (qeps - qnm) / eps
297 call matrix_sln%add_value_pos(this%idxsymglo(iexg), derv)
298 rhs_sln(nodegwf_sln) = rhs_sln(nodegwf_sln) + derv * hswf
309 subroutine swf_gwf_cq(this, icnvg, isuppress_output, isolnid)
312 integer(I4B),
intent(inout) :: icnvg
313 integer(I4B),
intent(in) :: isuppress_output
314 integer(I4B),
intent(in) :: isolnid
317 call this%swf_gwf_calc_simvals()
324 call this%swf_gwf_add_to_flowja()
338 call this%obs%obs_da()
339 deallocate (this%obs)
351 deallocate (this%swf_ftype)
352 deallocate (this%filename)
369 allocate (this%swf_ftype)
371 allocate (this%filename)
374 call mem_allocate(this%ipr_input,
'IPR_INPUT', this%memoryPath)
375 call mem_allocate(this%ipr_flow,
'IPR_FLOW', this%memoryPath)
376 call mem_allocate(this%ifixedcond,
'IFIXEDCOND', this%memoryPath)
394 call mem_allocate(this%nodeswf, this%nexg,
'NODEM1', this%memoryPath)
395 call mem_allocate(this%nodegwf, this%nexg,
'NODEM2', this%memoryPath)
396 call mem_allocate(this%bedleak, this%nexg,
'BEDLEAK', this%memoryPath)
397 call mem_allocate(this%cfact, this%nexg,
'CFACT', this%memoryPath)
398 call mem_allocate(this%idxglo, this%nexg,
'IDXGLO', this%memoryPath)
399 call mem_allocate(this%idxsymglo, this%nexg,
'IDXSYMGLO', this%memoryPath)
400 call mem_allocate(this%simvals, this%nexg,
'SIMVALS', this%memoryPath)
405 function noder(this, model, cellid, iout)
411 integer(I4B),
dimension(:),
intent(in) :: cellid
412 integer(I4B),
intent(in) ::
iout
413 integer(I4B) ::
noder, node
415 if (model%dis%ndim == 1)
then
417 elseif (model%dis%ndim == 2)
then
418 node =
get_node(cellid(1), 1, cellid(2), &
419 model%dis%mshape(1), 1, &
422 node =
get_node(cellid(1), cellid(2), cellid(3), &
423 model%dis%mshape(1), &
424 model%dis%mshape(2), &
427 noder = model%dis%get_nodenumber(node, 0)
437 integer(I4B),
dimension(:),
intent(in) :: cellid
438 integer(I4B),
intent(in) ::
iout
440 character(len=*),
parameter :: fmtndim1 = &
442 character(len=*),
parameter :: fmtndim2 = &
443 "('(',i0,',',i0,')')"
444 character(len=*),
parameter :: fmtndim3 = &
445 "('(',i0,',',i0,',',i0,')')"
449 select case (model%dis%ndim)
451 write (
cellstr, fmtndim1) cellid(1)
453 write (
cellstr, fmtndim2) cellid(1), cellid(2)
455 write (
cellstr, fmtndim3) cellid(1), cellid(2), cellid(3)
470 integer(I4B) :: nodeswf, nodegwf
471 integer(I4B) :: ibdn1, ibdn2
476 do iexg = 1, this%nexg
478 nodeswf = this%nodeswf(iexg)
479 nodegwf = this%nodegwf(iexg)
480 ibdn1 = this%swfmodel%ibound(nodeswf)
481 ibdn2 = this%gwfmodel%ibound(nodegwf)
482 hswf = this%swfmodel%x(nodeswf)
483 hgwf = this%gwfmodel%x(nodegwf)
484 if (ibdn1 /= 0 .and. ibdn2 /= 0)
then
485 rrate = this%qcalc(iexg, hswf, hgwf)
487 this%simvals(iexg) = rrate
496 function qcalc(this, iexg, hswf, hgwf)
501 integer(I4B),
intent(in) :: iexg
502 real(dp),
intent(in) :: hswf
503 real(dp),
intent(in) :: hgwf
508 cond = this%get_cond(iexg, hswf, hgwf)
509 qcalc = cond * (hgwf - hswf)
525 integer(I4B),
intent(in) :: iexg
526 real(dp),
intent(in) :: hswf
527 real(dp),
intent(in) :: hgwf
529 integer(I4B) :: nodeswf
530 real(dp) :: range = 1.d-6
531 real(dp) :: depth_ups
533 real(dp) :: smooth_factor
535 real(dp) :: perimeter
538 area = this%cfact(iexg)
539 if (this%ifixedcond == 1)
then
540 get_cond = this%bedleak(iexg) * area
547 nodeswf = this%nodeswf(iexg)
548 depth_ups = max(hswf, hgwf) - this%swfmodel%dis%bot(nodeswf)
549 call squadratic(depth_ups, range, dydx, smooth_factor)
553 if (this%swfmodel%dfw%is2d == 0)
then
554 perimeter = this%get_wetted_perimeter(nodeswf, depth_ups)
555 area = area * perimeter
559 get_cond = smooth_factor * this%bedleak(iexg) * area
569 integer(I4B),
intent(in) :: nodeswf
570 real(dp),
intent(in) :: depth
572 integer(I4B) :: idcxs
576 idcxs = this%swfmodel%dfw%idcxs(nodeswf)
577 call this%swfmodel%dis%get_flow_width(nodeswf, nodeswf, 0, width, dummy)
578 wp = this%swfmodel%cxs%get_wetted_perimeter(idcxs, width, depth)
591 integer(I4B) :: idiag
596 if (
associated(this%swfmodel))
then
598 if (this%swfmodel%ibound(n) > 0)
then
599 flow = this%simvals(i)
600 idiag = this%swfmodel%ia(n)
601 this%swfmodel%flowja(idiag) = this%swfmodel%flowja(idiag) + flow
605 if (
associated(this%gwfmodel))
then
607 if (this%gwfmodel%ibound(n) > 0)
then
608 flow = -this%simvals(i)
609 idiag = this%gwfmodel%ia(n)
610 this%gwfmodel%flowja(idiag) = this%gwfmodel%flowja(idiag) + flow
621 subroutine swf_gwf_bd(this, icnvg, isuppress_output, isolnid)
627 integer(I4B),
intent(inout) :: icnvg
628 integer(I4B),
intent(in) :: isuppress_output
629 integer(I4B),
intent(in) :: isolnid
631 character(len=LENBUDTXT),
dimension(1) :: budtxt
632 real(DP),
dimension(2, 1) :: budterm
633 real(DP) :: ratin, ratout
636 budtxt(1) =
' FLOW-JA-FACE'
642 if (
associated(this%swfmodel))
then
643 budterm(1, 1) = ratin
644 budterm(2, 1) = ratout
645 call this%swfmodel%model_bdentry(budterm, budtxt, this%name)
649 if (
associated(this%gwfmodel))
then
650 budterm(1, 1) = ratout
651 budterm(2, 1) = ratin
652 call this%gwfmodel%model_bdentry(budterm, budtxt, this%name)
657 call this%swf_gwf_chd_bd()
670 character(len=LENBUDTXT),
dimension(1) :: budtxt
673 real(DP),
dimension(2, 1) :: budterm
674 real(DP) :: ratin, ratout
678 budtxt(1) =
'FLOW-JA-FACE-CHD'
681 if (
associated(this%swfmodel))
then
686 if (this%swfmodel%ibound(n) < 0)
then
695 budterm(1, 1) = ratin
696 budterm(2, 1) = ratout
697 call this%swfmodel%model_bdentry(budterm, budtxt, this%name)
701 if (
associated(this%gwfmodel))
then
706 if (this%gwfmodel%ibound(n) < 0)
then
716 budterm(1, 1) = ratin
717 budterm(2, 1) = ratout
718 call this%gwfmodel%model_bdentry(budterm, budtxt, this%name)
730 integer(I4B) :: icbcfl, ibudfl
748 if (this%inobs /= 0)
then
749 call this%swf_gwf_save_simvals()
923 integer(I4B) :: iexg, n1, n2
925 character(len=LINELENGTH) :: node1str, node2str
927 character(len=*),
parameter :: fmtheader2 = &
928 "(/1x, 'SUMMARY OF EXCHANGE RATES FOR EXCHANGE ', a, ' WITH ID ', i0, /, &
929 &2a16, 4a16, /, 96('-'))"
930 character(len=*),
parameter :: fmtdata = &
934 call this%swf_gwf_bdsav()
937 if (this%ipr_flow /= 0)
then
938 write (
iout, fmtheader2) trim(adjustl(this%name)), this%id,
'NODEM1', &
939 'NODEM2',
'COND',
'X_M1',
'X_M2',
'FLOW'
940 do iexg = 1, this%nexg
941 n1 = this%nodeswf(iexg)
942 n2 = this%nodegwf(iexg)
943 flow = this%simvals(iexg)
944 call this%swfmodel%dis%noder_to_string(n1, node1str)
945 call this%gwfmodel%dis%noder_to_string(n2, node2str)
946 write (
iout, fmtdata) trim(adjustl(node1str)), &
947 trim(adjustl(node2str)), &
948 this%bedleak(iexg), this%swfmodel%x(n1), &
949 this%gwfmodel%x(n2), flow
954 call this%obs%obs_ot()
979 if (this%obs%npakobs > 0)
then
980 call this%obs%obs_bd_clear()
981 do i = 1, this%obs%npakobs
982 obsrv => this%obs%pakobs(i)%obsrv
983 do j = 1, obsrv%indxbnds_count
984 iexg = obsrv%indxbnds(j)
986 select case (obsrv%ObsTypeId)
987 case (
'FLOW-JA-FACE')
988 n1 = this%nodeswf(iexg)
989 n2 = this%nodegwf(iexg)
990 v = this%simvals(iexg)
992 errmsg =
'Unrecognized observation type: '// &
993 trim(obsrv%ObsTypeId)
997 call this%obs%SaveOneSimval(obsrv, v)
1011 logical(LGP) :: is_connected
1013 is_connected = .false.
1016 if (
associated(this%gwfmodel, model))
then
1017 is_connected = .true.
1020 if (
associated(this%swfmodel, model))
then
1021 is_connected = .true.
subroutine, public addbaseexchangetolist(list, exchange)
Add the exchange object (BaseExchangeType) to a list.
class(basemodeltype) function, pointer, public getbasemodelfromlist(list, idx)
This module contains the BudgetModule.
subroutine, public rate_accumulator(flow, rin, rout)
@ brief Rate accumulator subroutine
This module contains simulation constants.
integer(i4b), parameter linelength
maximum length of a standard line
integer(i4b), parameter lenpackagename
maximum length of the package name
integer(i4b), parameter lenftype
maximum length of a package type (DIS, WEL, OC, etc.)
real(dp), parameter dzero
real constant zero
integer(i4b), parameter lenbudtxt
maximum length of a budget component names
integer(i4b) function, public get_node(ilay, irow, icol, nlay, nrow, ncol)
Get node number, given layer, row, and column indices for a structured grid. If any argument is inval...
This module defines variable data types.
type(listtype), public basemodellist
type(listtype), public baseexchangelist
real(dp) function, public get_perturbation(x)
Calculate a numerical perturbation given the value of x.
character(len=lenmempath) function create_mem_path(component, subcomponent, context)
returns the path to the memory object
This module contains the derived types ObserveType and ObsDataType.
This module contains the derived type ObsType.
subroutine, public obs_cr(obs, inobs)
@ brief Create a new ObsType object
This module contains simulation methods.
subroutine, public store_error(msg, terminate)
Store an error message.
integer(i4b) function, public count_errors()
Return number of errors.
subroutine, public store_error_filename(filename, terminate)
Store the erroring file name.
subroutine, public store_error_unit(iunit, terminate)
Store the file unit number.
This module contains simulation variables.
character(len=maxcharlen) errmsg
error message string
integer(i4b), dimension(:), allocatable model_loc_idx
equals the local index into the basemodel list (-1 when not available)
integer(i4b) iout
file unit number for simulation output
subroutine squadratic(x, range, dydx, y)
@ brief sQuadratic
This module contains the SwfGwfExchangeModule Module.
integer(i4b) function noder(this, model, cellid, iout)
character(len=20) function cellstr(this, model, cellid, iout)
subroutine swf_gwf_mc(this, matrix_sln)
@ brief Map connections
subroutine swf_gwf_fc(this, kiter, matrix_sln, rhs_sln, inwtflag)
@ brief Fill coefficients
subroutine initialize(this, filename, name, swf_ftype, id, m1_id, m2_id, input_mempath)
@ brief Initialize SWF GWF exchange
subroutine swf_gwf_ac(this, sparse)
@ brief Add connections
subroutine swf_gwf_cq(this, icnvg, isuppress_output, isolnid)
@ brief Calculate flow
real(dp) function qcalc(this, iexg, hswf, hgwf)
@ brief Calculate flow
subroutine swf_gwf_save_simvals(this)
@ brief Save simulated flow observations
subroutine swf_gwf_add_to_flowja(this)
Add exchange flow to each model flowja diagonal position so that residual is calculated correctly.
real(dp) function get_wetted_perimeter(this, nodeswf, depth)
@ brief Get wetted perimeter for swf channel model
subroutine swf_gwf_ot(this)
@ brief Output
subroutine allocate_scalars(this)
@ brief Allocate scalars
subroutine swf_gwf_da(this)
@ brief Deallocate
real(dp) function get_cond(this, iexg, hswf, hgwf)
@ brief Calculate conductance
subroutine swf_gwf_bd(this, icnvg, isuppress_output, isolnid)
@ brief Budget
logical(lgp) function swf_gwf_connects_model(this, model)
Should return true when the exchange should be added to the solution where the model resides.
subroutine swf_gwf_bdsav(this)
@ brief Budget save
subroutine swf_gwf_calc_simvals(this)
Calculate flow rates for the exchanges and store them in a member array.
subroutine allocate_arrays(this)
Allocate array data, using the number of connected nodes.
subroutine swf_gwf_chd_bd(this)
@ brief swf-gwf-chd-bd
Surface Water Flow (SWF) Module.
subroutine, public table_cr(this, name, title)
Highest level model type. All models extend this parent type.