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

Data Types

type  gwfgweexchangetype
 

Functions/Subroutines

subroutine, public gwfgwe_cr (filename, id, m1_id, m2_id)
 Create a new GWF to GWE exchange object. More...
 
subroutine set_model_pointers (this)
 Allocate and read. More...
 
subroutine exg_df (this)
 Define the GwfGwe Exchange object. More...
 
subroutine exg_ar (this)
 Allocate and read. More...
 
subroutine gwfconn2gweconn (this, gwfModel, gweModel)
 Link GWE connections to GWF connections or exchanges. More...
 
subroutine link_connections (this, gweConn, gwfConn)
 Links a GWE connection to its GWF counterpart. More...
 
subroutine exg_da (this)
 Deallocate memory. More...
 
subroutine allocate_scalars (this)
 Allocate GwfGwe exchange scalars. More...
 
subroutine gwfbnd2gwefmi (this)
 Call routines in FMI that will set pointers to the necessary flow data (SIMVALS and SIMTOMVR) stored within each GWF flow package. More...
 

Function/Subroutine Documentation

◆ allocate_scalars()

subroutine gwfgweexchangemodule::allocate_scalars ( class(gwfgweexchangetype)  this)

Definition at line 511 of file exg-gwfgwe.f90.

512  ! -- modules
514  ! -- dummy
515  class(GwfGweExchangeType) :: this
516  !
517  call mem_allocate(this%m1_idx, 'M1ID', this%memoryPath)
518  call mem_allocate(this%m2_idx, 'M2ID', this%memoryPath)
519  this%m1_idx = 0
520  this%m2_idx = 0

◆ exg_ar()

subroutine gwfgweexchangemodule::exg_ar ( class(gwfgweexchangetype)  this)

Definition at line 181 of file exg-gwfgwe.f90.

182  ! -- modules
184  use dismodule, only: distype
185  use disvmodule, only: disvtype
186  use disumodule, only: disutype
187  ! -- dummy
188  class(GwfGweExchangeType) :: this
189  ! -- local
190  class(BaseModelType), pointer :: mb => null()
191  type(GwfModelType), pointer :: gwfmodel => null()
192  type(GweModelType), pointer :: gwemodel => null()
193  ! -- formats
194  character(len=*), parameter :: fmtdiserr = &
195  "('GWF and GWE Models do not have the same discretization for exchange&
196  & ',a,'.&
197  & GWF Model has ', i0, ' user nodes and ', i0, ' reduced nodes.&
198  & GWE Model has ', i0, ' user nodes and ', i0, ' reduced nodes.&
199  & Ensure discretization packages, including IDOMAIN, are identical.')"
200  character(len=*), parameter :: fmtidomerr = &
201  "('GWF and GWE Models do not have the same discretization for exchange&
202  & ',a,'.&
203  & GWF Model and GWE Model have different IDOMAIN arrays.&
204  & Ensure discretization packages, including IDOMAIN, are identical.')"
205  !
206  ! -- set gwfmodel
207  mb => getbasemodelfromlist(basemodellist, this%m1_idx)
208  select type (mb)
209  type is (gwfmodeltype)
210  gwfmodel => mb
211  end select
212  !
213  ! -- set gwemodel
214  mb => getbasemodelfromlist(basemodellist, this%m2_idx)
215  select type (mb)
216  type is (gwemodeltype)
217  gwemodel => mb
218  end select
219  !
220  ! -- Check to make sure sizes are identical
221  if (gwemodel%dis%nodes /= gwfmodel%dis%nodes .or. &
222  gwemodel%dis%nodesuser /= gwfmodel%dis%nodesuser) then
223  write (errmsg, fmtdiserr) trim(this%name), &
224  gwfmodel%dis%nodesuser, &
225  gwfmodel%dis%nodes, &
226  gwemodel%dis%nodesuser, &
227  gwemodel%dis%nodes
228  call store_error(errmsg, terminate=.true.)
229  end if
230  !
231  ! -- Make sure idomains are identical
232  select type (gwfdis => gwfmodel%dis)
233  type is (distype)
234  select type (gwedis => gwemodel%dis)
235  type is (distype)
236  if (.not. all(gwfdis%idomain == gwedis%idomain)) then
237  write (errmsg, fmtidomerr) trim(this%name)
238  call store_error(errmsg, terminate=.true.)
239  end if
240  end select
241  type is (disvtype)
242  select type (gwedis => gwemodel%dis)
243  type is (disvtype)
244  if (.not. all(gwfdis%idomain == gwedis%idomain)) then
245  write (errmsg, fmtidomerr) trim(this%name)
246  call store_error(errmsg, terminate=.true.)
247  end if
248  end select
249  type is (disutype)
250  select type (gwedis => gwemodel%dis)
251  type is (disutype)
252  if (.not. all(gwfdis%idomain == gwedis%idomain)) then
253  write (errmsg, fmtidomerr) trim(this%name)
254  call store_error(errmsg, terminate=.true.)
255  end if
256  end select
257  end select
258  !
259  ! -- setup pointers to gwf variables allocated in gwf_ar
260  gwemodel%fmi%gwfhead => gwfmodel%x
261  call mem_checkin(gwemodel%fmi%gwfhead, &
262  'GWFHEAD', gwemodel%fmi%memoryPath, &
263  'X', gwfmodel%memoryPath)
264  gwemodel%fmi%gwfsat => gwfmodel%npf%sat
265  call mem_checkin(gwemodel%fmi%gwfsat, &
266  'GWFSAT', gwemodel%fmi%memoryPath, &
267  'SAT', gwfmodel%npf%memoryPath)
268  gwemodel%fmi%gwfspdis => gwfmodel%npf%spdis
269  call mem_checkin(gwemodel%fmi%gwfspdis, &
270  'GWFSPDIS', gwemodel%fmi%memoryPath, &
271  'SPDIS', gwfmodel%npf%memoryPath)
272  gwemodel%fmi%igwfspdis = gwfmodel%npf%icalcspdis
273  !
274  ! -- setup pointers to the flow storage rates. GWF strg arrays are
275  ! available after the gwf_ar routine is called.
276  if (gwemodel%inest > 0) then
277  if (gwfmodel%insto > 0) then
278  gwemodel%fmi%gwfstrgss => gwfmodel%sto%strgss
279  gwemodel%fmi%igwfstrgss = 1
280  if (gwfmodel%sto%iusesy == 1) then
281  gwemodel%fmi%gwfstrgsy => gwfmodel%sto%strgsy
282  gwemodel%fmi%igwfstrgsy = 1
283  end if
284  end if
285  end if
286  !
287  ! -- Set a pointer to conc in buy
288  if (gwfmodel%inbuy > 0) then
289  call gwfmodel%buy%set_concentration_pointer(gwemodel%name, gwemodel%x, &
290  gwemodel%ibound)
291  end if
292  !
293  ! -- Set a pointer to conc (which could be a temperature) in vsc
294  if (gwfmodel%invsc > 0) then
295  call gwfmodel%vsc%set_concentration_pointer(gwemodel%name, gwemodel%x, &
296  gwemodel%ibound, 1)
297  end if
298  !
299  ! -- transfer the boundary package information from gwf to gwe
300  call this%gwfbnd2gwefmi()
301  !
302  ! -- if mover package is active, then set a pointer to it's budget object
303  if (gwfmodel%inmvr /= 0) then
304  gwemodel%fmi%mvrbudobj => gwfmodel%mvr%budobj
305  end if
306  !
307  ! -- connect Connections
308  call this%gwfconn2gweconn(gwfmodel, gwemodel)
Definition: Dis.f90:1
Structured grid discretization.
Definition: Dis.f90:23
Unstructured grid discretization.
Definition: Disu.f90:30
Vertex grid discretization.
Definition: Disv.f90:25
Here is the call graph for this function:

◆ exg_da()

subroutine gwfgweexchangemodule::exg_da ( class(gwfgweexchangetype)  this)

Definition at line 499 of file exg-gwfgwe.f90.

500  ! -- modules
502  ! -- dummy
503  class(GwfGweExchangeType) :: this
504  !
505  call mem_deallocate(this%m1_idx)
506  call mem_deallocate(this%m2_idx)

◆ exg_df()

subroutine gwfgweexchangemodule::exg_df ( class(gwfgweexchangetype)  this)

Definition at line 131 of file exg-gwfgwe.f90.

132  ! -- modules
134  ! -- dummy
135  class(GwfGweExchangeType) :: this
136  ! -- local
137  class(BaseModelType), pointer :: mb => null()
138  type(GwfModelType), pointer :: gwfmodel => null()
139  type(GweModelType), pointer :: gwemodel => null()
140  !
141  ! -- set gwfmodel
142  mb => getbasemodelfromlist(basemodellist, this%m1_idx)
143  select type (mb)
144  type is (gwfmodeltype)
145  gwfmodel => mb
146  end select
147  !
148  ! -- set gwemodel
149  mb => getbasemodelfromlist(basemodellist, this%m2_idx)
150  select type (mb)
151  type is (gwemodeltype)
152  gwemodel => mb
153  end select
154  !
155  ! -- Check to make sure that flow is solved before transport and in a
156  ! different IMS solution
157  if (gwfmodel%idsoln >= gwemodel%idsoln) then
158  write (errmsg, '(3a)') 'Problem with GWF-GWE exchange ', trim(this%name), &
159  '. The GWF model must be solved by a different IMS than the GWE model. &
160  &Furthermore, the IMS specified for GWF must be listed in mfsim.nam &
161  &before the IMS for GWE.'
162  call store_error(errmsg, terminate=.true.)
163  end if
164  !
165  ! -- Set pointer to flowja
166  gwemodel%fmi%gwfflowja => gwfmodel%flowja
167  call mem_checkin(gwemodel%fmi%gwfflowja, &
168  'GWFFLOWJA', gwemodel%fmi%memoryPath, &
169  'FLOWJA', gwfmodel%memoryPath)
170 
171  !
172  ! -- Set the npf flag so that specific discharge is available for
173  ! transport calculations if dispersion is active
174  if (gwemodel%incnd > 0) then
175  gwfmodel%npf%icalcspdis = 1
176  end if
Here is the call graph for this function:

◆ gwfbnd2gwefmi()

subroutine gwfgweexchangemodule::gwfbnd2gwefmi ( class(gwfgweexchangetype)  this)

Definition at line 526 of file exg-gwfgwe.f90.

527  ! -- dummy
528  class(GwfGweExchangeType) :: this
529  ! -- local
530  integer(I4B) :: ngwfpack, ip, iterm, imover
531  class(BaseModelType), pointer :: mb => null()
532  type(GwfModelType), pointer :: gwfmodel => null()
533  type(GweModelType), pointer :: gwemodel => null()
534  class(BndType), pointer :: packobj => null()
535  !
536  ! -- set gwfmodel
537  mb => getbasemodelfromlist(basemodellist, this%m1_idx)
538  select type (mb)
539  type is (gwfmodeltype)
540  gwfmodel => mb
541  end select
542  !
543  ! -- set gwemodel
544  mb => getbasemodelfromlist(basemodellist, this%m2_idx)
545  select type (mb)
546  type is (gwemodeltype)
547  gwemodel => mb
548  end select
549  !
550  ! -- Call routines in FMI that will set pointers to the necessary flow
551  ! data (SIMVALS and SIMTOMVR) stored within each GWF flow package
552  ngwfpack = gwfmodel%bndlist%Count()
553  iterm = 1
554  do ip = 1, ngwfpack
555  packobj => getbndfromlist(gwfmodel%bndlist, ip)
556  call gwemodel%fmi%gwfpackages(iterm)%set_pointers( &
557  'SIMVALS', &
558  packobj%memoryPath, packobj%input_mempath)
559  iterm = iterm + 1
560  !
561  ! -- If a mover is active for this package, then establish a separate
562  ! pointer link for the mover flows stored in SIMTOMVR
563  imover = packobj%imover
564  if (packobj%isadvpak /= 0) imover = 0
565  if (imover /= 0) then
566  call gwemodel%fmi%gwfpackages(iterm)%set_pointers( &
567  'SIMTOMVR', &
568  packobj%memoryPath, packobj%input_mempath)
569  iterm = iterm + 1
570  end if
571  end do
Here is the call graph for this function:

◆ gwfconn2gweconn()

subroutine gwfgweexchangemodule::gwfconn2gweconn ( class(gwfgweexchangetype)  this,
type(gwfmodeltype), pointer  gwfModel,
type(gwemodeltype), pointer  gweModel 
)
Parameters
thisthis exchange
gwfmodelthe flow model
gwemodelthe energy transport model

Definition at line 313 of file exg-gwfgwe.f90.

314  ! -- modules
315  use simmodule, only: store_error
316  use simvariablesmodule, only: iout
318  ! -- dummy
319  class(GwfGweExchangeType) :: this !< this exchange
320  type(GwfModelType), pointer :: gwfModel !< the flow model
321  type(GweModelType), pointer :: gweModel !< the energy transport model
322  ! -- local
323  class(SpatialModelConnectionType), pointer :: conn => null()
324  class(*), pointer :: objPtr => null()
325  class(GweGweConnectionType), pointer :: gweConn => null()
326  class(GwfGwfConnectionType), pointer :: gwfConn => null()
327  class(GwfExchangeType), pointer :: gwfEx => null()
328  integer(I4B) :: ic1, ic2, iex
329  integer(I4B) :: gwfConnIdx, gwfExIdx
330  logical(LGP) :: areEqual
331  !
332  ! loop over all connections
333  gweloop: do ic1 = 1, baseconnectionlist%Count()
334  !
335  conn => get_smc_from_list(baseconnectionlist, ic1)
336  if (.not. associated(conn%owner, gwemodel)) cycle gweloop
337  !
338  ! start with a GWE conn.
339  objptr => conn
340  gweconn => castasgwegweconnection(objptr)
341  gwfconnidx = -1
342  gwfexidx = -1
343  !
344  ! find matching GWF conn. in same list
345  gwfloop: do ic2 = 1, baseconnectionlist%Count()
346  conn => get_smc_from_list(baseconnectionlist, ic2)
347  !
348  if (associated(conn%owner, gwfmodel)) then
349  objptr => conn
350  gwfconn => castasgwfgwfconnection(objptr)
351  !
352  ! A model can have multiple exchanges, even connecting the same two
353  ! models. Require that the GWF models match those referenced by the
354  ! GWE exchange before comparing node lists, otherwise a GWE exchange
355  ! could be linked to the wrong GWF-GWF exchange.
356  if (gwfconn%gwfExchange%v_model1%name /= &
357  gweconn%gweExchange%gwfmodelname1) cycle
358  if (gwfconn%gwfExchange%v_model2%name /= &
359  gweconn%gweExchange%gwfmodelname2) cycle
360  !
361  ! then, connecting the same nodes nrs will be
362  ! sufficient evidence of equality
363  areequal = (gwfconn%gwfExchange%nexg == gweconn%gweExchange%nexg)
364  if (areequal) then
365  areequal = all(gwfconn%prim_exchange%nodem1 == &
366  gweconn%prim_exchange%nodem1)
367  areequal = areequal .and. all(gwfconn%prim_exchange%nodem2 == &
368  gweconn%prim_exchange%nodem2)
369  end if
370  if (areequal) then
371  ! same DIS, same exchange: link and go to next GWE conn.
372  write (iout, '(/6a)') 'Linking exchange ', &
373  trim(gweconn%prim_exchange%name), &
374  ' to ', trim(gwfconn%prim_exchange%name), &
375  ' (using interface model) for GWE model ', &
376  trim(gwemodel%name)
377  gwfconnidx = ic2
378  call this%link_connections(gweconn, gwfconn)
379  exit gwfloop
380  end if
381  end if
382  end do gwfloop
383  !
384  ! fallback option: coupling to old gwfgwf exchange,
385  ! (this will go obsolete at some point)
386  if (gwfconnidx == -1) then
387  gwfloopexg: do iex = 1, baseexchangelist%Count()
388  gwfex => getgwfexchangefromlist(baseexchangelist, iex)
389  !
390  ! -- There is no guarantee that iex is a gwfExg, in which case
391  ! it will return as null. cycle if so.
392  if (.not. associated(gwfex)) cycle gwfloopexg
393  !
394  if (associated(gwfex%model1, gwfmodel) .or. &
395  associated(gwfex%model2, gwfmodel)) then
396  !
397  ! require that the GWF models match those referenced by the GWE
398  ! exchange, otherwise a GWE exchange could be linked to the wrong
399  ! GWF-GWF exchange
400  if (gwfex%v_model1%name /= gweconn%gweExchange%gwfmodelname1) cycle
401  if (gwfex%v_model2%name /= gweconn%gweExchange%gwfmodelname2) cycle
402 
403  ! check exchanges have same node counts
404  areequal = size(gwfex%nodem1) == size(gweconn%prim_exchange%nodem1)
405  ! then, connecting the same nodes nrs will be
406  ! sufficient evidence of equality
407  if (areequal) &
408  areequal = all(gwfex%nodem1 == gweconn%prim_exchange%nodem1)
409  if (areequal) &
410  areequal = all(gwfex%nodem2 == gweconn%prim_exchange%nodem2)
411  if (areequal) then
412  ! link exchange to connection
413  write (iout, '(/6a)') 'Linking exchange ', &
414  trim(gweconn%prim_exchange%name), &
415  ' to ', trim(gwfex%name), ' for GWE model ', &
416  trim(gwemodel%name)
417  gwfexidx = iex
418  if (gweconn%owns_exchange) then
419  gweconn%gweExchange%gwfsimvals => gwfex%simvals
420  call mem_checkin(gweconn%gweExchange%gwfsimvals, &
421  'GWFSIMVALS', gweconn%gweExchange%memoryPath, &
422  'SIMVALS', gwfex%memoryPath)
423  end if
424  !
425  !cdl link up mvt to mvr
426  if (gwfex%inmvr > 0) then
427  if (gweconn%owns_exchange) then
428  !cdl todo: check and make sure gweEx has mvt active
429  call gweconn%gweExchange%mvt%set_pointer_mvrbudobj( &
430  gwfex%mvr%budobj)
431  end if
432  end if
433  !
434  if (associated(gwfex%model2, gwfmodel)) gweconn%exgflowSign = -1
435  gweconn%gweInterfaceModel%fmi%flows_from_file = .false.
436  !
437  exit gwfloopexg
438  end if
439  end if
440  !
441  end do gwfloopexg
442  end if
443  !
444  if (gwfconnidx == -1 .and. gwfexidx == -1) then
445  ! none found, report
446  write (errmsg, '(/6a)') 'Missing GWF-GWF exchange when connecting GWE'// &
447  ' model ', trim(gwemodel%name), ' with exchange ', &
448  trim(gweconn%prim_exchange%name), ' to GWF model ', &
449  trim(gwfmodel%name)
450  call store_error(errmsg, terminate=.true.)
451  end if
452  !
453  end do gweloop
This module contains simulation methods.
Definition: Sim.f90:10
subroutine, public store_error(msg, terminate)
Store an error message.
Definition: Sim.f90:92
This module contains simulation variables.
Definition: SimVariables.f90:9
integer(i4b) iout
file unit number for simulation output
Here is the call graph for this function:

◆ gwfgwe_cr()

subroutine, public gwfgweexchangemodule::gwfgwe_cr ( character(len=*), intent(in)  filename,
integer(i4b), intent(in)  id,
integer(i4b), intent(in)  m1_id,
integer(i4b), intent(in)  m2_id 
)

Definition at line 46 of file exg-gwfgwe.f90.

47  ! -- modules
49  ! -- dummy
50  character(len=*), intent(in) :: filename
51  integer(I4B), intent(in) :: id
52  integer(I4B), intent(in) :: m1_id
53  integer(I4B), intent(in) :: m2_id
54  ! -- local
55  class(BaseExchangeType), pointer :: baseexchange => null()
56  type(GwfGweExchangeType), pointer :: exchange => null()
57  character(len=20) :: cint
58  !
59  ! -- Create a new exchange and add it to the baseexchangelist container
60  allocate (exchange)
61  baseexchange => exchange
62  call addbaseexchangetolist(baseexchangelist, baseexchange)
63  !
64  ! -- Assign id and name
65  exchange%id = id
66  write (cint, '(i0)') id
67  exchange%name = 'GWF-GWE_'//trim(adjustl(cint))
68  exchange%memoryPath = exchange%name
69  !
70  ! -- allocate scalars
71  call exchange%allocate_scalars()
72  !
73  ! -- NB: convert from id to local model index in base model list
74  exchange%m1_idx = model_loc_idx(m1_id)
75  exchange%m2_idx = model_loc_idx(m2_id)
76  !
77  ! -- set model pointers
78  call exchange%set_model_pointers()
integer(i4b), dimension(:), allocatable model_loc_idx
equals the local index into the basemodel list (-1 when not available)
Here is the call graph for this function:
Here is the caller graph for this function:

◆ link_connections()

subroutine gwfgweexchangemodule::link_connections ( class(gwfgweexchangetype)  this,
class(gwegweconnectiontype), pointer  gweConn,
class(gwfgwfconnectiontype), pointer  gwfConn 
)
Parameters
thisthis exchange
gweconnGWE connection
gwfconnGWF connection

Definition at line 458 of file exg-gwfgwe.f90.

459  ! -- modules
461  ! -- dummy
462  class(GwfGweExchangeType) :: this !< this exchange
463  class(GweGweConnectionType), pointer :: gweConn !< GWE connection
464  class(GwfGwfConnectionType), pointer :: gwfConn !< GWF connection
465  !
466  !gweConn%exgflowja => gwfConn%exgflowja
467  if (gweconn%owns_exchange) then
468  gweconn%gweExchange%gwfsimvals => gwfconn%gwfExchange%simvals
469  call mem_checkin(gweconn%gweExchange%gwfsimvals, &
470  'GWFSIMVALS', gweconn%gweExchange%memoryPath, &
471  'SIMVALS', gwfconn%gwfExchange%memoryPath)
472  end if
473  !
474  !cdl link up mvt to mvr
475  if (gwfconn%gwfExchange%inmvr > 0) then
476  if (gweconn%owns_exchange) then
477  !cdl todo: check and make sure gweEx has mvt active
478  call gweconn%gweExchange%mvt%set_pointer_mvrbudobj( &
479  gwfconn%gwfExchange%mvr%budobj)
480  end if
481  end if
482  !
483  if (associated(gwfconn%gwfExchange%model2, gwfconn%owner)) then
484  gweconn%exgflowSign = -1
485  end if
486  !
487  ! fmi flows are not read from file
488  gweconn%gweInterfaceModel%fmi%flows_from_file = .false.
489  !
490  ! set concentration pointer for buoyancy
491  !call gwfConn%gwfInterfaceModel%buy%set_concentration_pointer( &
492  ! gweConn%gweModel%name, &
493  ! gweConn%conc, &
494  ! gweConn%icbound)

◆ set_model_pointers()

subroutine gwfgweexchangemodule::set_model_pointers ( class(gwfgweexchangetype)  this)

Definition at line 83 of file exg-gwfgwe.f90.

84  ! -- dummy
85  class(GwfGweExchangeType) :: this
86  ! -- local
87  class(BaseModelType), pointer :: mb => null()
88  type(GwfModelType), pointer :: gwfmodel => null()
89  type(GweModelType), pointer :: gwemodel => null()
90  !
91  ! -- set gwfmodel
92  gwfmodel => null()
93  mb => getbasemodelfromlist(basemodellist, this%m1_idx)
94  select type (mb)
95  type is (gwfmodeltype)
96  gwfmodel => mb
97  end select
98  !
99  ! -- set gwemodel
100  gwemodel => null()
101  mb => getbasemodelfromlist(basemodellist, this%m2_idx)
102  select type (mb)
103  type is (gwemodeltype)
104  gwemodel => mb
105  end select
106  !
107  ! -- Verify that gwf model is of the correct type
108  if (.not. associated(gwfmodel)) then
109  write (errmsg, '(3a)') 'Problem with GWF-GWE exchange ', trim(this%name), &
110  '. Specified GWF Model does not appear to be of the correct type.'
111  call store_error(errmsg, terminate=.true.)
112  end if
113  !
114  ! -- Verify that gwe model is of the correct type
115  if (.not. associated(gwemodel)) then
116  write (errmsg, '(3a)') 'Problem with GWF-GWE exchange ', trim(this%name), &
117  '. Specified GWF Model does not appear to be of the correct type.'
118  call store_error(errmsg, terminate=.true.)
119  end if
120  !
121  ! -- Tell transport model fmi flows are not read from file
122  gwemodel%fmi%flows_from_file = .false.
123  !
124  ! -- Set a pointer to the GWF bndlist. This will allow the transport model
125  ! to look through the flow packages and establish a link to GWF flows
126  gwemodel%fmi%gwfbndlist => gwfmodel%bndlist
Here is the call graph for this function: