MODFLOW 6  version 6.7.0.dev0
USGS Modular Hydrologic Model
spatialmodelconnectionmodule Module Reference

Data Types

type  spatialmodelconnectiontype
 Class to manage spatial connection of a model to one or more models of the same type. Spatial connection here means that the model domains (spatial discretization) are adjacent and connected via DisConnExchangeType object(s). The connection itself is a Numerical Exchange as well, and part of a Numerical Solution providing the amat and rhs. More...
 

Functions/Subroutines

subroutine spatialconnection_ctor (this, model, exchange, name)
 Construct the spatial connection base. More...
 
subroutine createmodelhalo (this)
 Find all models that might participate in this interface. More...
 
recursive subroutine addmodelneighbors (this, model_id, virtual_exchanges, depth, is_root, mask)
 Add neighbors and nbrs-of-nbrs to the model tree. More...
 
subroutine spatialcon_df (this)
 Define this connection, this is where the discretization (DISU) for the interface model is. More...
 
subroutine spatialcon_ar (this)
 Allocate the connection,. More...
 
subroutine spatialcon_setmodelptrs (this)
 set model pointers to connection More...
 
subroutine spatialcon_connect (this)
 map interface model connections to our sparse matrix, More...
 
subroutine maskownerconnections (this)
 Mask the owner's connections. More...
 
subroutine createcoefficientmatrix (this, sparse)
 Add connections, handled by the interface model,. More...
 
subroutine validateconnection (this)
 Validate this connection. More...
 
subroutine cfg_dv (this, var_name, subcomp_name, map_type, sync_stages, exg_var_name)
 Add a variable from the interface model to be synchronized at the configured stages by copying from the source memory in the models/exchanges that are part. More...
 
class(spatialmodelconnectiontype) function, pointer, public cast_as_smc (obj)
 Cast to SpatialModelConnectionType. More...
 
subroutine, public add_smc_to_list (list, conn)
 Add connection to a list. More...
 
class(spatialmodelconnectiontype) function, pointer, public get_smc_from_list (list, idx)
 Get the connection from a list. More...
 

Function/Subroutine Documentation

◆ add_smc_to_list()

subroutine, public spatialmodelconnectionmodule::add_smc_to_list ( type(listtype), intent(inout)  list,
class(spatialmodelconnectiontype), intent(in), pointer  conn 
)
Parameters
[in,out]listthe list
[in]connthe connection

Definition at line 697 of file SpatialModelConnection.f90.

698  implicit none
699  ! -- dummy
700  type(ListType), intent(inout) :: list !< the list
701  class(SpatialModelConnectionType), pointer, intent(in) :: conn !< the connection
702  ! -- local
703  class(*), pointer :: obj
704  !
705  obj => conn
706  call list%Add(obj)
Here is the caller graph for this function:

◆ addmodelneighbors()

recursive subroutine spatialmodelconnectionmodule::addmodelneighbors ( class(spatialmodelconnectiontype this,
integer(i4b)  model_id,
type(listtype virtual_exchanges,
integer(i4b), value  depth,
logical(lgp)  is_root,
integer(i4b), optional  mask 
)
private
Parameters
thisthis connection
model_idthe model (id) to add neighbors for
virtual_exchangeslist with all virtual exchanges
depththe maximal number of exchanges between
is_roottrue when called for neighbor from primary exchange
maskdon't add this one as a neighbor

Definition at line 154 of file SpatialModelConnection.f90.

158  class(SpatialModelConnectionType) :: this !< this connection
159  integer(I4B) :: model_id !< the model (id) to add neighbors for
160  type(ListType) :: virtual_exchanges !< list with all virtual exchanges
161  integer(I4B), value :: depth !< the maximal number of exchanges between
162  logical(LGP) :: is_root !< true when called for neighbor from primary exchange
163  integer(I4B), optional :: mask !< don't add this one as a neighbor
164  ! local
165  integer(I4B) :: i, n
166  class(VirtualExchangeType), pointer :: v_exg
167  integer(I4B) :: neighbor_id
168  integer(I4B) :: model_mask
169  type(STLVecInt) :: models_at_depth !< model ids at a certain depth, to
170  !! recurse on for nbrs-of-nbrs search
171 
172  if (.not. present(mask)) then
173  model_mask = 0
174  else
175  model_mask = mask
176  end if
177 
178  call models_at_depth%init()
179 
180  if (is_root) then
181  ! first layer in the recursive search
182  call models_at_depth%push_back_unique(model_id)
183 
184  ! fetch primary neighbor
185  if (this%prim_exchange%v_model1%id == this%owner%id) then
186  neighbor_id = this%prim_exchange%v_model2%id
187  else
188  neighbor_id = this%prim_exchange%v_model1%id
189  end if
190  ! add
191  call models_at_depth%push_back_unique(neighbor_id)
192  call this%halo_models%push_back_unique(neighbor_id)
193  call this%halo_exchanges%push_back_unique(this%prim_exchange%id)
194  else
195  ! find all direct neighbors of the model and add them,
196  ! avoiding duplicates
197  do i = 1, virtual_exchanges%Count()
198  neighbor_id = -1
199  v_exg => get_virtual_exchange_from_list(virtual_exchanges, i)
200  if (v_exg%v_model1%id == model_id) then
201  neighbor_id = v_exg%v_model2%id
202  else if (v_exg%v_model2%id == model_id) then
203  neighbor_id = v_exg%v_model1%id
204  end if
205 
206  ! check if there is a neighbor, and it is not masked
207  ! (to prevent back-and-forth connections)
208  if (neighbor_id > 0) then
209  ! check if masked
210  if (neighbor_id == model_mask) cycle
211  call models_at_depth%push_back_unique(neighbor_id)
212  call this%halo_models%push_back_unique(neighbor_id)
213  call this%halo_exchanges%push_back_unique(v_exg%id)
214  end if
215  end do
216  end if
217 
218  depth = depth - 1
219  if (depth == 0) then
220  ! and we're done with this branch
221  call models_at_depth%destroy()
222  return
223  end if
224 
225  ! now recurse on the neighbors up to the specified depth
226  do n = 1, models_at_depth%size
227  call this%addModelNeighbors(models_at_depth%at(n), virtual_exchanges, &
228  depth, .false., model_id)
229  end do
230 
231  ! we're done with the tree
232  call models_at_depth%destroy()
233 
class(virtualexchangetype) function, pointer, public get_virtual_exchange(exg_id)
Returns a virtual exchange with the specified id.
Here is the call graph for this function:

◆ cast_as_smc()

class(spatialmodelconnectiontype) function, pointer, public spatialmodelconnectionmodule::cast_as_smc ( class(*), intent(inout), pointer  obj)
Parameters
[in,out]objobject to be cast
Returns
the instance of SpatialModelConnectionType

Definition at line 681 of file SpatialModelConnection.f90.

682  implicit none
683  class(*), pointer, intent(inout) :: obj !< object to be cast
684  class(SpatialModelConnectionType), pointer :: res !< the instance of SpatialModelConnectionType
685  !
686  res => null()
687  if (.not. associated(obj)) return
688  !
689  select type (obj)
690  class is (spatialmodelconnectiontype)
691  res => obj
692  end select
Here is the caller graph for this function:

◆ cfg_dv()

subroutine spatialmodelconnectionmodule::cfg_dv ( class(spatialmodelconnectiontype this,
character(len=*)  var_name,
character(len=*)  subcomp_name,
integer(i4b)  map_type,
integer(i4b), dimension(:)  sync_stages,
character(len=*), optional  exg_var_name 
)
Parameters
thisthis connection
var_namename of variable, e.g. "K11"
subcomp_namesubcomponent, e.g. "NPF"
map_typetype of variable map
sync_stagesstages to sync
exg_var_nameneeded for exchange variables, e.g. SIMVALS

Definition at line 652 of file SpatialModelConnection.f90.

654  class(SpatialModelConnectionType) :: this !< this connection
655  character(len=*) :: var_name !< name of variable, e.g. "K11"
656  character(len=*) :: subcomp_name !< subcomponent, e.g. "NPF"
657  integer(I4B) :: map_type !< type of variable map
658  integer(I4B), dimension(:) :: sync_stages !< stages to sync
659  character(len=*), optional :: exg_var_name !< needed for exchange variables, e.g. SIMVALS
660  ! local
661  type(DistVarType), pointer :: dist_var => null()
662  class(*), pointer :: obj
663 
664  if (.not. present(exg_var_name)) exg_var_name = ''
665 
666  allocate (dist_var)
667  dist_var%var_name = var_name
668  dist_var%subcomp_name = subcomp_name
669  dist_var%comp_name = this%interface_model%name
670  dist_var%map_type = map_type
671  dist_var%sync_stages = sync_stages
672  dist_var%exg_var_name = exg_var_name
673 
674  obj => dist_var
675  call this%iface_dist_vars%Add(obj)
676 

◆ createcoefficientmatrix()

subroutine spatialmodelconnectionmodule::createcoefficientmatrix ( class(spatialmodelconnectiontype this,
type(sparsematrix), intent(inout)  sparse 
)
Parameters
thisthis connection
[in,out]sparsethe sparse matrix with the cell connections

Definition at line 610 of file SpatialModelConnection.f90.

611  use simmodule, only: ustop
612  class(SpatialModelConnectionType) :: this !< this connection
613  type(sparsematrix), intent(inout) :: sparse !< the sparse matrix with the cell connections
614 
615  call sparse%sort()
616  call this%matrix%init(sparse, this%memoryPath)
617 
This module contains simulation methods.
Definition: Sim.f90:10
subroutine, public ustop(stopmess, ioutlocal)
Stop the simulation.
Definition: Sim.f90:312
Here is the call graph for this function:

◆ createmodelhalo()

subroutine spatialmodelconnectionmodule::createmodelhalo ( class(spatialmodelconnectiontype this)
private
Parameters
thisthis connection

Definition at line 141 of file SpatialModelConnection.f90.

142  class(SpatialModelConnectionType) :: this !< this connection
143 
144  call this%halo_models%init()
145  call this%halo_exchanges%init()
146 
147  call this%addModelNeighbors(this%owner%id, virtual_exchange_list, &
148  this%exg_stencil_depth, .true.)
149 

◆ get_smc_from_list()

class(spatialmodelconnectiontype) function, pointer, public spatialmodelconnectionmodule::get_smc_from_list ( type(listtype), intent(inout)  list,
integer(i4b), intent(in)  idx 
)
Parameters
[in,out]listthe list
[in]idxthe index of the connection
Returns
the returned connection

Definition at line 711 of file SpatialModelConnection.f90.

712  type(ListType), intent(inout) :: list !< the list
713  integer(I4B), intent(in) :: idx !< the index of the connection
714  class(SpatialModelConnectionType), pointer :: res !< the returned connection
715 
716  ! local
717  class(*), pointer :: obj
718  obj => list%GetItem(idx)
719  res => cast_as_smc(obj)
Here is the call graph for this function:
Here is the caller graph for this function:

◆ maskownerconnections()

subroutine spatialmodelconnectionmodule::maskownerconnections ( class(spatialmodelconnectiontype this)
private

Determine which connections are handled by the interface model (using the connections object in its discretization) and

Parameters
thisthe connection

Definition at line 331 of file SpatialModelConnection.f90.

332  use csrutilsmodule, only: getcsrindex
333  class(SpatialModelConnectionType) :: this !< the connection
334  ! local
335  integer(I4B) :: ipos, n, m, nloc, mloc, csr_idx
336  type(ConnectionsType), pointer :: conn
337 
338  ! set the mask on connections that are calculated by the interface model
339  conn => this%interface_model%dis%con
340  do n = 1, conn%nodes
341  ! only for connections internal to the owning model
342  if (.not. this%ig_builder%idxToGlobal(n)%v_model == this%owner) then
343  cycle
344  end if
345  nloc = this%ig_builder%idxToGlobal(n)%index
346 
347  do ipos = conn%ia(n) + 1, conn%ia(n + 1) - 1
348  m = conn%ja(ipos)
349  if (.not. this%ig_builder%idxToGlobal(m)%v_model == this%owner) then
350  cycle
351  end if
352  mloc = this%ig_builder%idxToGlobal(m)%index
353 
354  if (conn%mask(ipos) > 0) then
355  ! calculated by interface model, set local model's mask to zero
356  csr_idx = getcsrindex(nloc, mloc, this%owner%ia, this%owner%ja)
357  if (csr_idx == -1) then
358  ! this can only happen with periodic boundary conditions,
359  ! then there is no need to set the mask
360  if (this%ig_builder%isPeriodic(nloc, mloc)) cycle
361 
362  write (*, *) 'Error: cannot find cell connection in global system'
363  call ustop()
364  end if
365 
366  if (this%owner%dis%con%mask(csr_idx) > 0) then
367  call this%owner%dis%con%set_mask(csr_idx, 0)
368  else
369  ! edge case, this connection is already being calculated
370  ! so we ignore it here. This can happen in the overlap
371  ! between two different exchanges when a larger stencil
372  ! (XT3D) is applied.
373  call conn%set_mask(ipos, 0)
374  end if
375  end if
376  end do
377  end do
378 
integer(i4b) function, public getcsrindex(i, j, ia, ja)
Return index for element i,j in CSR storage,.
Definition: CsrUtils.f90:13
Here is the call graph for this function:

◆ spatialcon_ar()

subroutine spatialmodelconnectionmodule::spatialcon_ar ( class(spatialmodelconnectiontype this)
private
Parameters
thisthis connection

Definition at line 266 of file SpatialModelConnection.f90.

267  class(SpatialModelConnectionType) :: this !< this connection
268  ! local
269  integer(I4B) :: iface_idx, glob_idx
270  class(GridConnectionType), pointer :: gc
271 
272  ! fill mapping to global index (which can be
273  ! done now because moffset is set in sln_df)
274  gc => this%ig_builder
275  do iface_idx = 1, gc%nrOfCells
276  glob_idx = gc%idxToGlobal(iface_idx)%index + &
277  gc%idxToGlobal(iface_idx)%v_model%moffset%get()
278  gc%idxToGlobalIdx(iface_idx) = glob_idx
279  end do
280 

◆ spatialcon_connect()

subroutine spatialmodelconnectionmodule::spatialcon_connect ( class(spatialmodelconnectiontype this)
private
Parameters
thisthis connection

Definition at line 306 of file SpatialModelConnection.f90.

307  class(SpatialModelConnectionType) :: this !< this connection
308  ! local
309  type(sparsematrix) :: sparse
310  class(MatrixBaseType), pointer :: matrix_base
311 
312  call sparse%init(this%neq, this%neq, 7)
313  call this%interface_model%model_ac(sparse)
314 
315  ! create amat from sparse
316  call this%createCoefficientMatrix(sparse)
317  call sparse%destroy()
318 
319  ! map connections
320  matrix_base => this%matrix
321  call this%interface_model%model_mc(matrix_base)
322  call this%maskOwnerConnections()
323 

◆ spatialcon_df()

subroutine spatialmodelconnectionmodule::spatialcon_df ( class(spatialmodelconnectiontype this)
Parameters
thisthis connection

Definition at line 239 of file SpatialModelConnection.f90.

240  class(SpatialModelConnectionType) :: this !< this connection
241  ! local
242  integer(I4B) :: i
243  class(VirtualModelType), pointer :: v_model
244 
245  ! create the grid connection data structure
246  this%nr_connections = this%getNrOfConnections()
247  call this%ig_builder%construct(this%owner, &
248  this%nr_connections, &
249  this%name)
250  this%ig_builder%internalStencilDepth = this%int_stencil_depth
251  this%ig_builder%exchangeStencilDepth = this%exg_stencil_depth
252  this%ig_builder%haloExchanges => this%halo_exchanges
253  do i = 1, this%halo_models%size
254  v_model => get_virtual_model(this%halo_models%at(i))
255  call this%ig_builder%addToRegionalModels(v_model)
256  end do
257  call this%setupGridConnection()
258 
259  this%neq = this%ig_builder%nrOfCells
260  call this%allocateArrays()
261 

◆ spatialcon_setmodelptrs()

subroutine spatialmodelconnectionmodule::spatialcon_setmodelptrs ( class(spatialmodelconnectiontype this)
private
Parameters
thisthis connection

Definition at line 285 of file SpatialModelConnection.f90.

286  class(SpatialModelConnectionType) :: this !< this connection
287 
288  ! point x, ibound, and rhs to connection
289  this%interface_model%x => this%x
290  call mem_checkin(this%interface_model%x, 'X', &
291  this%interface_model%memoryPath, 'X', &
292  this%memoryPath)
293  this%interface_model%rhs => this%rhs
294  call mem_checkin(this%interface_model%rhs, 'RHS', &
295  this%interface_model%memoryPath, 'RHS', &
296  this%memoryPath)
297  this%interface_model%ibound => this%active
298  call mem_checkin(this%interface_model%ibound, 'IBOUND', &
299  this%interface_model%memoryPath, 'IBOUND', &
300  this%memoryPath)
301 

◆ spatialconnection_ctor()

subroutine spatialmodelconnectionmodule::spatialconnection_ctor ( class(spatialmodelconnectiontype this,
class(numericalmodeltype), intent(in), pointer  model,
class(disconnexchangetype), intent(in), pointer  exchange,
character(len=*), intent(in)  name 
)

This constructor is typically called from a derived class.

Parameters
thisthe connection
[in]modelthe model that owns the connection
[in]exchangethe primary exchange from which the connection is created
[in]namethe connection name (for memory management mostly)

Definition at line 111 of file SpatialModelConnection.f90.

112  class(SpatialModelConnectionType) :: this !< the connection
113  class(NumericalModelType), intent(in), pointer :: model !< the model that owns the connection
114  class(DisConnExchangeType), intent(in), pointer :: exchange !< the primary exchange from which
115  !! the connection is created
116  character(len=*), intent(in) :: name !< the connection name (for memory management mostly)
117 
118  this%name = name
119  this%memoryPath = create_mem_path(this%name)
120 
121  this%owner => model
122  this%prim_exchange => exchange
123 
124  allocate (this%ig_builder)
125  allocate (this%halo_models)
126  allocate (this%halo_exchanges)
127  allocate (this%matrix)
128  call this%allocateScalars()
129 
130  this%int_stencil_depth = 1
131  this%exg_stencil_depth = 1
132  this%nr_connections = 0
133 
134  ! this should be set in derived ctor
135  this%interface_model => null()
136 
Here is the call graph for this function:
Here is the caller graph for this function:

◆ validateconnection()

subroutine spatialmodelconnectionmodule::validateconnection ( class(spatialmodelconnectiontype this)
Parameters
thisthis connection

Definition at line 622 of file SpatialModelConnection.f90.

623  use simvariablesmodule, only: errmsg
624  use simmodule, only: store_error
625  class(SpatialModelConnectionType) :: this !< this connection
626  ! local
627  class(DisConnExchangeType), pointer :: conEx => null()
628 
629  conex => this%prim_exchange
630  if (conex%ixt3d > 0) then
631  ! if XT3D, we need these angles:
632  if (conex%v_model1%con_ianglex%get() == 0) then
633  write (errmsg, '(a,a,a,a,a)') 'XT3D configured on the exchange ', &
634  trim(conex%name), ' but the discretization in model ', &
635  trim(conex%v_model1%name), ' has no ANGLDEGX specified'
636  call store_error(errmsg)
637  end if
638  if (conex%v_model2%con_ianglex%get() == 0) then
639  write (errmsg, '(a,a,a,a,a)') 'XT3D configured on the exchange ', &
640  trim(conex%name), ' but the discretization in model ', &
641  trim(conex%v_model2%name), ' has no ANGLDEGX specified'
642  call store_error(errmsg)
643  end if
644  end if
645 
subroutine, public store_error(msg, terminate)
Store an error message.
Definition: Sim.f90:92
This module contains simulation variables.
Definition: SimVariables.f90:9
character(len=maxcharlen) errmsg
error message string
Here is the call graph for this function: