MODFLOW 6  version 6.5.0.dev2
MODFLOW 6 Code Documentation
GwfGwfConnection.f90
Go to the documentation of this file.
2  use kindmodule, only: i4b, dp, lgp
3  use constantsmodule, only: dzero, done, dem6, lenvarname, &
5  use csrutilsmodule, only: getcsrindex
6  use sparsemodule, only: sparsematrix
8  use simmodule, only: ustop
16  use gwfnpfmodule, only: gwfnpftype
17  use gwfbuymodule, only: gwfbuytype
18  use basedismodule, only: disbasetype
22  use simstagesmodule
24 
25  implicit none
26  private
27 
28  public :: castasgwfgwfconnection
29 
30  !> Connecting a GWF model to other models in space, implements
31  !! NumericalExchangeType so the solution can used this object to determine
32  !! the coefficients for the coupling between two adjacent models.
33  !!
34  !! Two connections are created per exchange between model1 and model2:
35  !! one to manage the coefficients in the matrix rows for model1, and
36  !! the other to do the same for model2.
37  !<
39 
40  class(gwfmodeltype), pointer :: gwfmodel => null() !< the model for which this connection exists
41  class(gwfexchangetype), pointer :: gwfexchange => null() !< the primary exchange, cast to its concrete type
42  class(gwfinterfacemodeltype), pointer :: gwfinterfacemodel => null() !< the interface model
43  integer(I4B), pointer :: ixt3donexchange => null() !< run XT3D on the interface,
44  !! 0 = don't, 1 = matrix, 2 = rhs
45  integer(I4B) :: iout = 0 !< the list file for the interface model
46 
47  contains
48  procedure :: gwfgwfconnection_ctor
49  generic, public :: construct => gwfgwfconnection_ctor
50 
51  ! overriding NumericalExchangeType
52  procedure :: exg_df => gwfgwfcon_df
53  procedure :: exg_ar => gwfgwfcon_ar
54  procedure :: exg_rp => gwfgwfcon_rp
55  procedure :: exg_ad => gwfgwfcon_ad
56  procedure :: exg_cf => gwfgwfcon_cf
57  procedure :: exg_fc => gwfgwfcon_fc
58  procedure :: exg_da => gwfgwfcon_da
59  procedure :: exg_cq => gwfgwfcon_cq
60  procedure :: exg_bd => gwfgwfcon_bd
61  procedure :: exg_ot => gwfgwfcon_ot
62 
63  ! overriding 'protected'
64  procedure :: validateconnection
65 
66  ! local stuff
67  procedure, private :: cfg_dist_vars
68  procedure, private :: allocatescalars
69  procedure, private :: setgridextent
70  procedure, private :: validategwfexchange
71  procedure, private :: setflowtoexchange
72  procedure, private :: setflowtomodel
73  procedure, private :: setnpfedgeprops
74 
75  end type gwfgwfconnectiontype
76 
77 contains
78 
79  !> @brief Basic construction of the connection
80  !<
81  subroutine gwfgwfconnection_ctor(this, model, gwfEx)
83  use inputoutputmodule, only: openfile
84  class(gwfgwfconnectiontype) :: this !< the connection
85  class(numericalmodeltype), pointer :: model !< the model owning this connection,
86  !! this must of course be a GwfModelType
87  class(disconnexchangetype), pointer :: gwfEx !< the exchange the interface model is created for
88  ! local
89  character(len=LINELENGTH) :: fname
90  character(len=LENCOMPONENTNAME) :: name
91  class(*), pointer :: objPtr
92  logical(LGP) :: write_ifmodel_listfile = .false.
93 
94  objptr => model
95  this%gwfModel => castasgwfmodel(objptr)
96  objptr => gwfex
97  this%gwfExchange => castasgwfexchange(objptr)
98 
99  if (gwfex%v_model1%is_local .and. gwfex%v_model2%is_local) then
100  this%owns_exchange = (gwfex%v_model1 == model)
101  else
102  this%owns_exchange = .true.
103  end if
104 
105  if (gwfex%v_model1 == model) then
106  write (name, '(a,i0)') 'GWFCON1_', gwfex%id
107  else
108  write (name, '(a,i0)') 'GWFCON2_', gwfex%id
109  end if
110 
111  ! .lst file for interface model
112  if (write_ifmodel_listfile) then
113  fname = trim(name)//'.im.lst'
114  call openfile(this%iout, 0, fname, 'LIST', filstat_opt='REPLACE')
115  write (this%iout, '(4a)') 'Creating GWF-GWF connection for model ', &
116  trim(this%gwfModel%name), ' from exchange ', &
117  trim(gwfex%name)
118  end if
119 
120  ! first call base constructor
121  call this%SpatialModelConnectionType%spatialConnection_ctor(model, &
122  gwfex, &
123  name)
124 
125  call this%allocateScalars()
126 
127  this%typename = 'GWF-GWF'
128 
129  ! determine the required size of the interface grid
130  call this%setGridExtent()
131 
132  allocate (this%gwfInterfaceModel)
133  this%interface_model => this%gwfInterfaceModel
134 
135  end subroutine gwfgwfconnection_ctor
136 
137  !> @brief Define the connection
138  !!
139  !! This sets up the GridConnection (for creating the
140  !! interface grid), creates and defines the interface
141  !< model
142  subroutine gwfgwfcon_df(this)
143  class(gwfgwfconnectiontype) :: this !< this connection
144  ! local
145  character(len=LENCOMPONENTNAME) :: imName !< the interface model's name
146  integer(I4B) :: i
147 
148  ! this sets up the GridConnection
149  call this%spatialcon_df()
150 
151  ! Now grid conn is defined, we create the interface model
152  ! here, and the remainder of this routine is define.
153  ! we basically follow the logic that is present in sln_df()
154  if (this%prim_exchange%v_model1 == this%owner) then
155  write (imname, '(a,i0)') 'GWFIM1_', this%gwfExchange%id
156  else
157  write (imname, '(a,i0)') 'GWFIM2_', this%gwfExchange%id
158  end if
159  call this%gwfInterfaceModel%gwfifm_cr(imname, this%iout, this%ig_builder)
160  call this%gwfInterfaceModel%set_idsoln(this%gwfModel%idsoln)
161  this%gwfInterfaceModel%npf%satomega = this%gwfModel%npf%satomega
162  this%gwfInterfaceModel%npf%ixt3d = this%iXt3dOnExchange
163  call this%gwfInterfaceModel%model_df()
164 
165  ! Take these settings from the owning model
166  this%gwfInterfaceModel%npf%ik22 = this%gwfModel%npf%ik22
167  this%gwfInterfaceModel%npf%ik33 = this%gwfModel%npf%ik33
168  this%gwfInterfaceModel%npf%iwetdry = this%gwfModel%npf%iwetdry
169  this%gwfInterfaceModel%npf%iangle1 = this%gwfModel%npf%iangle1
170  this%gwfInterfaceModel%npf%iangle2 = this%gwfModel%npf%iangle2
171  this%gwfInterfaceModel%npf%iangle3 = this%gwfModel%npf%iangle3
172 
173  call this%cfg_dist_vars()
174 
175  if (this%gwfInterfaceModel%npf%ixt3d > 0) then
176  this%gwfInterfaceModel%npf%iangle1 = 1
177  this%gwfInterfaceModel%npf%iangle2 = 1
178  this%gwfInterfaceModel%npf%iangle3 = 1
179  end if
180 
181  ! set defaults
182  do i = 1, size(this%gwfInterfaceModel%npf%angle1)
183  this%gwfInterfaceModel%npf%angle1 = 0.0_dp
184  end do
185  do i = 1, size(this%gwfInterfaceModel%npf%angle2)
186  this%gwfInterfaceModel%npf%angle2 = 0.0_dp
187  end do
188  do i = 1, size(this%gwfInterfaceModel%npf%angle3)
189  this%gwfInterfaceModel%npf%angle3 = 0.0_dp
190  end do
191 
192  ! point X, RHS, IBOUND to connection
193  call this%spatialcon_setmodelptrs()
194 
195  ! connect interface model to spatial connection
196  call this%spatialcon_connect()
197 
198  end subroutine gwfgwfcon_df
199 
200  !> @brief Configure distributed variables for this interface model
201  !<
202  subroutine cfg_dist_vars(this)
203  class(gwfgwfconnectiontype) :: this !< the connection
204 
205  call this%cfg_dv('X', '', sync_nds, &
207  call this%cfg_dv('IBOUND', '', sync_nds, &
209  call this%cfg_dv('XOLD', '', sync_nds, (/stg_bfr_exg_ad, stg_bfr_exg_cf/))
210  call this%cfg_dv('ICELLTYPE', 'NPF', sync_nds, (/stg_bfr_con_ar/))
211  call this%cfg_dv('K11', 'NPF', sync_nds, (/stg_bfr_con_ar/))
212  call this%cfg_dv('K22', 'NPF', sync_nds, (/stg_bfr_con_ar/))
213  call this%cfg_dv('K33', 'NPF', sync_nds, (/stg_bfr_con_ar/))
214  if (this%gwfInterfaceModel%npf%iangle1 == 1) then
215  call this%cfg_dv('ANGLE1', 'NPF', sync_nds, (/stg_bfr_con_ar/))
216  end if
217  if (this%gwfInterfaceModel%npf%iangle2 == 1) then
218  call this%cfg_dv('ANGLE2', 'NPF', sync_nds, (/stg_bfr_con_ar/))
219  end if
220  if (this%gwfInterfaceModel%npf%iangle3 == 1) then
221  call this%cfg_dv('ANGLE3', 'NPF', sync_nds, (/stg_bfr_con_ar/))
222  end if
223  if (this%gwfInterfaceModel%npf%iwetdry == 1) then
224  call this%cfg_dv('WETDRY', 'NPF', sync_nds, (/stg_bfr_con_ar/))
225  end if
226  call this%cfg_dv('TOP', 'DIS', sync_nds, (/stg_bfr_con_ar/))
227  call this%cfg_dv('BOT', 'DIS', sync_nds, (/stg_bfr_con_ar/))
228  call this%cfg_dv('AREA', 'DIS', sync_nds, (/stg_bfr_con_ar/))
229  if (this%gwfInterfaceModel%inbuy > 0) then
230  call this%cfg_dv('DENSE', 'BUY', sync_nds, (/stg_bfr_exg_cf/))
231  end if
232 
233  end subroutine cfg_dist_vars
234 
235  !> @brief Set the required size of the interface grid from
236  !< the configuration
237  subroutine setgridextent(this)
238  class(gwfgwfconnectiontype) :: this !< the connection
239  ! local
240 
241  this%iXt3dOnExchange = this%gwfExchange%ixt3d
242  if (this%iXt3dOnExchange > 0) then
243  this%exg_stencil_depth = 2
244  if (this%gwfModel%npf%ixt3d > 0) then
245  this%int_stencil_depth = 2
246  end if
247  end if
248 
249  end subroutine setgridextent
250 
251  !> @brief allocation of scalars in the connection
252  !<
253  subroutine allocatescalars(this)
255  class(gwfgwfconnectiontype) :: this !< the connection
256  ! local
257 
258  call mem_allocate(this%iXt3dOnExchange, 'IXT3DEXG', this%memoryPath)
259 
260  end subroutine allocatescalars
261 
262  !> @brief Allocate and read the connection
263  !<
264  subroutine gwfgwfcon_ar(this)
266  class(gwfgwfconnectiontype) :: this !< this connection
267  ! local
268 
269  ! check if we can construct an interface model
270  ! NB: only makes sense after the models' allocate&read have been
271  ! called, which is why we do it here
272  call this%validateConnection()
273 
274  ! allocate and read base
275  call this%spatialcon_ar()
276 
277  ! ... and now the interface model
278  call this%gwfInterfaceModel%model_ar()
279 
280  ! AR the movers and obs through the exchange
281  if (this%owns_exchange) then
282  if (this%gwfExchange%inmvr > 0) then
283  call this%gwfExchange%mvr%mvr_ar()
284  end if
285  if (this%gwfExchange%inobs > 0) then
286  call this%gwfExchange%obs%obs_ar()
287  end if
288  end if
289 
290  end subroutine gwfgwfcon_ar
291 
292  !> @brief Read time varying data when required
293  !<
294  subroutine gwfgwfcon_rp(this)
295  class(gwfgwfconnectiontype) :: this !< this connection
296 
297  ! Call exchange rp routines
298  if (this%owns_exchange) then
299  call this%gwfExchange%exg_rp()
300  end if
301 
302  return
303  end subroutine gwfgwfcon_rp
304 
305  !> @brief Advance this connection
306  !<
307  subroutine gwfgwfcon_ad(this)
308  class(gwfgwfconnectiontype) :: this !< this connection
309 
310  ! this triggers the BUY density calculation
311  !if (this%gwfInterfaceModel%inbuy > 0) call this%gwfInterfaceModel%buy%buy_ad()
312 
313  if (this%owns_exchange) then
314  call this%gwfExchange%exg_ad()
315  end if
316 
317  end subroutine gwfgwfcon_ad
318 
319  subroutine gwfgwfcon_cf(this, kiter)
320  class(gwfgwfconnectiontype) :: this !< this connection
321  integer(I4B), intent(in) :: kiter !< the iteration counter
322 
323  call this%SpatialModelConnectionType%spatialcon_cf(kiter)
324 
325  ! CF the movers through the exchange
326  if (this%owns_exchange) then
327  if (this%gwfExchange%inmvr > 0) then
328  call this%gwfExchange%mvr%xmvr_cf()
329  end if
330  end if
331 
332  end subroutine gwfgwfcon_cf
333 
334  !> @brief Write the calculated coefficients into the global
335  !< system matrix and the rhs
336  subroutine gwfgwfcon_fc(this, kiter, matrix_sln, rhs_sln, inwtflag)
337  class(gwfgwfconnectiontype) :: this !< this connection
338  integer(I4B), intent(in) :: kiter !< the iteration counter
339  class(matrixbasetype), pointer :: matrix_sln !< global system matrix coefficients
340  real(DP), dimension(:), intent(inout) :: rhs_sln !< global right-hand-side
341  integer(I4B), optional, intent(in) :: inwtflag !< newton-raphson flag
342  ! local
343 
344  call this%SpatialModelConnectionType%spatialcon_fc( &
345  kiter, matrix_sln, rhs_sln, inwtflag)
346 
347  ! FC the movers through the exchange; we cannot call
348  ! exg_fc() directly because it calculates matrix terms
349  if (this%owns_exchange) then
350  if (this%gwfExchange%inmvr > 0) then
351  call this%gwfExchange%mvr%mvr_fc()
352  end if
353  end if
354 
355  end subroutine gwfgwfcon_fc
356 
357  !> @brief Validate this connection
358  !! This is called before proceeding to construct
359  !! the interface model
360  !<
361  subroutine validateconnection(this)
362  use simvariablesmodule, only: errmsg
363  use simmodule, only: count_errors
364  class(gwfgwfconnectiontype) :: this !< this connection
365  ! local
366 
367  ! base validation (geometry/spatial)
368  call this%SpatialModelConnectionType%validateConnection()
369  call this%validateGwfExchange()
370 
371  ! abort on errors
372  if (count_errors() > 0) then
373  write (errmsg, '(a)') 'Errors occurred while processing exchange(s)'
374  call ustop()
375  end if
376 
377  end subroutine validateconnection
378 
379  !> @brief Validate the exchange, intercepting those
380  !! cases where two models have to be connected with an interface
381  !! model, where the individual configurations don't allow this
382  !!
383  !! Stops with error message on config mismatch
384  !<
385  subroutine validategwfexchange(this)
387  use simmodule, only: store_error
388  use gwfnpfmodule, only: gwfnpftype
389  class(gwfgwfconnectiontype) :: this !< this connection
390  ! local
391  class(gwfexchangetype), pointer :: gwfEx
392  class(*), pointer :: modelPtr
393  class(gwfmodeltype), pointer :: gwfModel1
394  class(gwfmodeltype), pointer :: gwfModel2
395  type(gwfbuytype), pointer :: buy1, buy2
396  logical(LGP) :: compatible
397 
398  gwfex => this%gwfExchange
399 
400  ! GNC not allowed
401  if (gwfex%ingnc /= 0 .and. gwfex%ixt3d /= 0) then
402  write (errmsg, '(2a)') 'Ghost node correction not supported '// &
403  'combined with XT3D for exchange ', trim(gwfex%name)
404  call store_error(errmsg)
405  end if
406  if (gwfex%ingnc /= 0 .and. simulation_mode == 'PARALLEL') then
407  write (errmsg, '(2a)') 'Ghost node correction not supported '// &
408  'in parallel run for exchange ', trim(gwfex%name)
409  call store_error(errmsg)
410  end if
411 
412  ! we cannot validate the remainder (yet) in parallel mode
413  if (.not. gwfex%v_model1%is_local) return
414  if (.not. gwfex%v_model2%is_local) return
415 
416  modelptr => this%gwfExchange%model1
417  gwfmodel1 => castasgwfmodel(modelptr)
418  modelptr => this%gwfExchange%model2
419  gwfmodel2 => castasgwfmodel(modelptr)
420 
421  if ((gwfmodel1%inbuy > 0 .and. gwfmodel2%inbuy == 0) .or. &
422  (gwfmodel1%inbuy == 0 .and. gwfmodel2%inbuy > 0)) then
423  write (errmsg, '(2a)') 'Buoyancy package should be enabled/disabled '// &
424  'simultaneously in models connected with the '// &
425  'interface model for exchange ', &
426  trim(gwfex%name)
427  call store_error(errmsg)
428 
429  end if
430 
431  if (gwfmodel1%inbuy > 0 .and. gwfmodel2%inbuy > 0) then
432  ! does not work with XT3D
433  if (this%iXt3dOnExchange > 0) then
434  write (errmsg, '(2a)') 'Connecting models with BUY package not '// &
435  'allowed with XT3D enabled on exchange ', &
436  trim(gwfex%name)
437  call store_error(errmsg)
438  end if
439 
440  ! check compatibility of buoyancy
441  compatible = .true.
442  buy1 => gwfmodel1%buy
443  buy2 => gwfmodel2%buy
444  if (buy1%iform /= buy2%iform) compatible = .false.
445  if (buy1%denseref /= buy2%denseref) compatible = .false.
446  if (buy1%nrhospecies /= buy2%nrhospecies) compatible = .false.
447  if (.not. all(buy1%drhodc == buy2%drhodc)) compatible = .false.
448  if (.not. all(buy1%crhoref == buy2%crhoref)) compatible = .false.
449  if (.not. all(buy1%cauxspeciesname == buy2%cauxspeciesname)) then
450  compatible = .false.
451  end if
452 
453  if (.not. compatible) then
454  write (errmsg, '(6a)') 'Buoyancy packages in model ', &
455  trim(gwfex%model1%name), ' and ', &
456  trim(gwfex%model2%name), &
457  ' should be equivalent to construct an '// &
458  ' interface model for exchange ', &
459  trim(gwfex%name)
460  call store_error(errmsg)
461  end if
462 
463  end if
464 
465  end subroutine validategwfexchange
466 
467  !> @brief Deallocate all resources
468  !<
469  subroutine gwfgwfcon_da(this)
470  use kindmodule, only: lgp
471  class(gwfgwfconnectiontype) :: this !< this connection
472  ! local
473  logical(LGP) :: isOpen
474 
475  ! scalars
476  call mem_deallocate(this%iXt3dOnExchange)
477 
478  call this%gwfInterfaceModel%model_da()
479  deallocate (this%gwfInterfaceModel)
480 
481  call this%spatialcon_da()
482 
483  inquire (this%iout, opened=isopen)
484  if (isopen) then
485  close (this%iout)
486  end if
487 
488  ! we need to deallocate the baseexchange we own:
489  if (this%owns_exchange) then
490  call this%gwfExchange%exg_da()
491  end if
492 
493  end subroutine gwfgwfcon_da
494 
495  !> @brief Calculate intra-cell flows
496  !! The calculation will be dispatched to the interface
497  !! model, and then mapped back to real-world cell ids.
498  !<
499  subroutine gwfgwfcon_cq(this, icnvg, isuppress_output, isolnid)
500  class(gwfgwfconnectiontype) :: this !< this connection
501  integer(I4B), intent(inout) :: icnvg !< convergence flag
502  integer(I4B), intent(in) :: isuppress_output !< suppress output when =1
503  integer(I4B), intent(in) :: isolnid !< solution id
504 
505  call this%gwfInterfaceModel%model_cq(icnvg, isuppress_output)
506 
507  call this%setFlowToExchange()
508 
509  call this%setFlowToModel()
510 
511  !cdl Could we allow GwfExchange to do this instead, using
512  ! simvals?
513  ! if needed, we add the edge properties to the model's NPF
514  ! package for its spdis calculation:
515  if (this%gwfModel%npf%icalcspdis == 1) then
516  call this%setNpfEdgeProps()
517  end if
518 
519  ! Add exchange flows to each model flowja diagonal. This used
520  ! to be done in setNpfEdgeProps, but there was a sign issue
521  ! and flowja was only updated if icalcspdis was 1 (it should
522  ! always be updated.
523  if (this%owns_exchange) then
524  call this%gwfExchange%gwf_gwf_add_to_flowja()
525  end if
526 
527  end subroutine gwfgwfcon_cq
528 
529  !> @brief Set the flows (flowja from interface model) to the
530  !< simvals in the exchange, leaving the budget calcution in there
531  subroutine setflowtoexchange(this)
532  use indexmapmodule
533  class(gwfgwfconnectiontype) :: this !< this connection
534  ! local
535  integer(I4B) :: i
536  class(gwfexchangetype), pointer :: gwfEx
537  type(indexmapsgntype), pointer :: map
538 
539  if (this%owns_exchange) then
540  gwfex => this%gwfExchange
541  map => this%interface_map%exchange_maps(this%interface_map%prim_exg_idx)
542 
543  ! use (half of) the exchange map in reverse:
544  do i = 1, size(map%src_idx)
545  if (map%sign(i) < 0) cycle ! simvals is defined from exg%m1 => exg%m2
546  gwfex%simvals(map%src_idx(i)) = &
547  this%gwfInterfaceModel%flowja(map%tgt_idx(i))
548  end do
549  end if
550 
551  end subroutine setflowtoexchange
552 
553  !> @brief Set the flows (flowja from the interface model) to
554  !< to the model, update the budget
555  subroutine setflowtomodel(this)
556  class(gwfgwfconnectiontype) :: this !< this connection
557  ! local
558  integer(I4B) :: n, m, ipos, iposLoc
559  integer(I4B) :: nLoc, mLoc
560  type(connectionstype), pointer :: imCon !< interface model connections
561  type(globalcelltype), dimension(:), pointer :: toGlobal !< map interface index to global cell
562 
563  ! for readability
564  imcon => this%gwfInterfaceModel%dis%con
565  toglobal => this%ig_builder%idxToGlobal
566 
567  do n = 1, this%neq
568  if (.not. toglobal(n)%v_model == this%owner) then
569  ! only add flows to own model
570  cycle
571  end if
572 
573  nloc = toglobal(n)%index
574 
575  do ipos = imcon%ia(n) + 1, imcon%ia(n + 1) - 1
576  if (imcon%mask(ipos) < 1) cycle ! skip this connection, it's masked so not determined by us
577 
578  m = imcon%ja(ipos)
579  mloc = toglobal(m)%index
580  if (toglobal(m)%v_model == this%owner) then
581 
582  ! internal, need to set flowja for n-m
583  iposloc = getcsrindex(nloc, mloc, this%gwfModel%ia, this%gwfModel%ja)
584 
585  ! update flowja with correct value
586  this%gwfModel%flowja(iposloc) = this%gwfInterfaceModel%flowja(ipos)
587 
588  end if
589  end do
590  end do
591 
592  end subroutine setflowtomodel
593 
594  !> @brief Set flowja as edge properties in the model,
595  !< so it can be used for e.g. specific discharge calculation
596  subroutine setnpfedgeprops(this)
597  class(gwfgwfconnectiontype) :: this !< this connection
598  ! local
599  integer(I4B) :: n, m, ipos, isym
600  integer(I4B) :: nLoc, mLoc
601  integer(I4B) :: ihc
602  real(DP) :: rrate
603  real(DP) :: area
604  real(DP) :: satThick
605  real(DP) :: nx, ny, nz
606  real(DP) :: cx, cy, cz
607  real(DP) :: conLen
608  real(DP) :: dist
609  real(DP) :: cl
610  logical :: nozee
611  type(connectionstype), pointer :: imCon !< interface model connections
612  class(gwfnpftype), pointer :: imNpf !< interface model npf package
613  class(disbasetype), pointer :: imDis !< interface model discretization
614  type(globalcelltype), dimension(:), pointer :: toGlobal !< map interface index to global cell
615 
616  ! for readability
617  imdis => this%gwfInterfaceModel%dis
618  imcon => this%gwfInterfaceModel%dis%con
619  imnpf => this%gwfInterfaceModel%npf
620  toglobal => this%ig_builder%idxToGlobal
621 
622  nozee = .false.
623  if (imnpf%ixt3d > 0) then
624  nozee = imnpf%xt3d%nozee
625  end if
626 
627  ! loop over flowja in the interface model and set edge properties
628  ! for flows crossing the boundary, and set flowja for internal
629  ! flows affected by the connection.
630  do n = 1, this%neq
631  if (.not. toglobal(n)%v_model == this%owner) then
632  ! only add flows to own model
633  cycle
634  end if
635 
636  nloc = toglobal(n)%index
637 
638  do ipos = imcon%ia(n) + 1, imcon%ia(n + 1) - 1
639  if (imcon%mask(ipos) < 1) then
640  ! skip this connection, it's masked so not determined by us
641  cycle
642  end if
643 
644  m = imcon%ja(ipos)
645  mloc = toglobal(m)%index
646 
647  if (.not. toglobal(m)%v_model == this%owner) then
648  ! boundary connection, set edge properties
649  isym = imcon%jas(ipos)
650  ihc = imcon%ihc(isym)
651  area = imcon%hwva(isym)
652  satthick = imnpf%calcSatThickness(n, m, ihc)
653  rrate = this%gwfInterfaceModel%flowja(ipos)
654 
655  call imdis%connection_normal(n, m, ihc, nx, ny, nz, ipos)
656  call imdis%connection_vector(n, m, nozee, imnpf%sat(n), imnpf%sat(m), &
657  ihc, cx, cy, cz, conlen)
658 
659  if (ihc == 0) then
660  ! check if n is below m
661  if (nz > 0) rrate = -rrate
662  else
663  area = area * satthick
664  end if
665 
666  cl = imcon%cl1(isym)
667  if (m < n) then
668  cl = imcon%cl2(isym)
669  end if
670  dist = conlen * cl / (imcon%cl1(isym) + imcon%cl2(isym))
671  call this%gwfModel%npf%set_edge_properties(nloc, ihc, rrate, area, &
672  nx, ny, dist)
673  end if
674  end do
675  end do
676 
677  end subroutine setnpfedgeprops
678 
679  !> @brief Calculate the budget terms for this connection, this is
680  !! dispatched to the GWF-GWF exchange
681  subroutine gwfgwfcon_bd(this, icnvg, isuppress_output, isolnid)
682  class(gwfgwfconnectiontype) :: this !< this connection
683  integer(I4B), intent(inout) :: icnvg !< convergence flag
684  integer(I4B), intent(in) :: isuppress_output !< suppress output when =1
685  integer(I4B), intent(in) :: isolnid !< solution id
686  ! local
687 
688  ! call exchange budget routine, also calls bd
689  ! for movers.
690  if (this%owns_exchange) then
691  call this%gwfExchange%exg_bd(icnvg, isuppress_output, isolnid)
692  end if
693 
694  end subroutine gwfgwfcon_bd
695 
696  !> @brief Write output for exchange (and calls
697  !< save on the budget)
698  subroutine gwfgwfcon_ot(this)
699  class(gwfgwfconnectiontype) :: this !< this connection
700  ! local
701 
702  ! Call exg_ot() here as it handles all output processing
703  ! based on gwfExchange%simvals(:), which was correctly
704  ! filled from gwfgwfcon
705  if (this%owns_exchange) then
706  call this%gwfExchange%exg_ot()
707  end if
708 
709  end subroutine gwfgwfcon_ot
710 
711  !> @brief Cast to GwfGwfConnectionType
712  !<
713  function castasgwfgwfconnection(obj) result(res)
714  implicit none
715  class(*), pointer, intent(inout) :: obj !< object to be cast
716  class(gwfgwfconnectiontype), pointer :: res !< the GwfGwfConnection
717 
718  res => null()
719  if (.not. associated(obj)) return
720 
721  select type (obj)
722  class is (gwfgwfconnectiontype)
723  res => obj
724  end select
725  return
726  end function castasgwfgwfconnection
727 
728 end module gwfgwfconnectionmodule
This module contains simulation constants.
Definition: Constants.f90:9
integer(i4b), parameter linelength
maximum length of a standard line
Definition: Constants.f90:44
integer(i4b), parameter lencomponentname
maximum length of a component name
Definition: Constants.f90:18
integer(i4b), parameter lenvarname
maximum length of a variable name
Definition: Constants.f90:17
real(dp), parameter dem6
real constant 1e-6
Definition: Constants.f90:108
real(dp), parameter dzero
real constant zero
Definition: Constants.f90:64
integer(i4b), parameter lenmempath
maximum length of the memory path
Definition: Constants.f90:26
real(dp), parameter done
real constant 1
Definition: Constants.f90:75
integer(i4b) function, public getcsrindex(i, j, ia, ja)
Return index for element i,j in CSR storage,.
Definition: CsrUtils.f90:13
integer(i4b), parameter, public sync_nds
synchronize over nodes
Refactoring issues towards parallel:
subroutine cfg_dist_vars(this)
Configure distributed variables for this interface model.
subroutine gwfgwfcon_cf(this, kiter)
subroutine gwfgwfcon_ad(this)
Advance this connection.
subroutine setflowtoexchange(this)
Set the flows (flowja from interface model) to the.
subroutine gwfgwfcon_cq(this, icnvg, isuppress_output, isolnid)
Calculate intra-cell flows The calculation will be dispatched to the interface model,...
subroutine gwfgwfcon_bd(this, icnvg, isuppress_output, isolnid)
Calculate the budget terms for this connection, this is dispatched to the GWF-GWF exchange.
class(gwfgwfconnectiontype) function, pointer, public castasgwfgwfconnection(obj)
Cast to GwfGwfConnectionType.
subroutine setnpfedgeprops(this)
Set flowja as edge properties in the model,.
subroutine validategwfexchange(this)
Validate the exchange, intercepting those cases where two models have to be connected with an interfa...
subroutine allocatescalars(this)
allocation of scalars in the connection
subroutine gwfgwfcon_fc(this, kiter, matrix_sln, rhs_sln, inwtflag)
Write the calculated coefficients into the global.
subroutine setgridextent(this)
Set the required size of the interface grid from.
subroutine gwfgwfcon_rp(this)
Read time varying data when required.
subroutine gwfgwfcon_ar(this)
Allocate and read the connection.
subroutine gwfgwfcon_df(this)
Define the connection.
subroutine validateconnection(this)
Validate this connection This is called before proceeding to construct the interface model.
subroutine setflowtomodel(this)
Set the flows (flowja from the interface model) to.
subroutine gwfgwfconnection_ctor(this, model, gwfEx)
Basic construction of the connection.
subroutine gwfgwfcon_ot(this)
Write output for exchange (and calls.
subroutine gwfgwfcon_da(this)
Deallocate all resources.
This module contains the GwfGwfExchangeModule Module.
Definition: exg-gwfgwf.f90:10
class(gwfexchangetype) function, pointer, public getgwfexchangefromlist(list, idx)
@ brief Get exchange from list
class(gwfexchangetype) function, pointer, public castasgwfexchange(obj)
@ brief Cast polymorphic object as exchange
Definition: gwf.f90:1
class(gwfmodeltype) function, pointer, public castasgwfmodel(model)
Cast to GWF model.
Definition: gwf.f90:1391
subroutine, public openfile(iu, iout, fname, ftype, fmtarg_opt, accarg_opt, filstat_opt, mode_opt)
Open a file.
Definition: InputOutput.f90:30
This module defines variable data types.
Definition: kind.f90:8
This module contains simulation methods.
Definition: Sim.f90:10
subroutine, public ustop(stopmess, ioutlocal)
Stop the simulation.
Definition: Sim.f90:315
subroutine, public store_error(msg, terminate)
Store an error message.
Definition: Sim.f90:92
integer(i4b) function, public count_errors()
Return number of errors.
Definition: Sim.f90:59
integer(i4b), parameter, public stg_bfr_exg_ad
before exchange advance (per solution)
Definition: SimStages.f90:21
integer(i4b), parameter, public stg_bfr_exg_cf
before exchange calculate (per solution)
Definition: SimStages.f90:22
integer(i4b), parameter, public stg_bfr_con_ar
before connection allocate read
Definition: SimStages.f90:17
This module contains simulation variables.
Definition: SimVariables.f90:9
character(len=maxcharlen) errmsg
error message string
character(len=linelength) simulation_mode
Data structure to hold a global cell identifier, using a pointer to the model and its local cell.
Exchange based on connection between discretizations of DisBaseType. The data specifies the connectio...
This class is used to construct the connections object for the interface model's spatial discretizati...
Connecting a GWF model to other models in space, implements NumericalExchangeType so the solution can...
Derived type for GwfExchangeType.
Definition: exg-gwfgwf.f90:47
The GWF Interface Model is a utility to calculate the solution's exchange coefficients from the inter...
Class to manage spatial connection of a model to one or more models of the same type....