MODFLOW 6  version 6.5.0.dev2
MODFLOW 6 Code Documentation
gridconnectionmodule Module Reference

Refactoring issues towards parallel: More...

Data Types

type  gridconnectiontype
 This class is used to construct the connections object for the interface model's spatial discretization/grid. More...
 

Functions/Subroutines

subroutine construct (this, model, nrOfPrimaries, connectionName)
 Construct the GridConnection and allocate the data structures for the primary connections. More...
 
subroutine connectprimaryexchange (this, primEx)
 Make connections for the primary exchange. More...
 
subroutine connectcell (this, idx1, v_model1, idx2, v_model2)
 Connect neighboring cells at the interface by storing them in the boundary cell and connected cell arrays. More...
 
subroutine addtoregionalmodels (this, v_model)
 Add a model to a list of all regional models. More...
 
subroutine extendconnection (this)
 Extend the connection topology to deal with higher levels of connectivity (neighbors-of-neighbors, etc.) More...
 
subroutine buildconnections (this)
 Builds a sparse matrix holding all cell connections,. More...
 
recursive subroutine addneighbors (this, cellNbrs, depth, mask, interior)
 
subroutine addremoteneighbors (this, cellNbrs, mask)
 Add cell neighbors across models using the stored exchange data structures. More...
 
subroutine addneighborcell (this, cellNbrs, newNbrIdx, v_nbr_model, mask)
 Add neighboring cell to tree structure. More...
 
recursive subroutine registerinterfacecells (this, cellWithNbrs)
 Recursively set interface cell indexes and. More...
 
subroutine addtoglobalmap (this, ifaceIdx, cell)
 Add entry to lookup table, inflating when necessary. More...
 
subroutine compressglobalmap (this)
 Compress lookup table to get rid of unused entries. More...
 
subroutine sortinterfacegrid (this)
 Soft cell ids in the interface grid such that. More...
 
subroutine makeprimaryconnections (this, sparse)
 Add primary connections to the sparse data structure. More...
 
recursive subroutine connectneighborcells (this, cell, sparse)
 Recursively add higher order connections (from cells neighboring the primarily connected cells) to the. More...
 
subroutine fillconnectiondatainternal (this)
 Fill connection data (ihc, cl1, ...) for. More...
 
subroutine fillconnectiondatafromexchanges (this)
 Fill connection data (ihc, cl1, ...) for. More...
 
subroutine createconnectionmask (this)
 Create the connection masks. More...
 
recursive subroutine maskinternalconnections (this, cell, nbrCell, level)
 Recursively mask connections, increasing the level as we go. More...
 
subroutine setmaskonconnection (this, cell, nbrCell, level)
 Set a mask on the connection from a cell to its neighbor, (and not the transposed!) not overwriting the current level. More...
 
integer(i4b) function getinterfaceindexbycell (this, cell)
 Get interface index from global cell. More...
 
integer(i4b) function getinterfaceindexbyindexmodel (this, index, v_model)
 Get interface index from a model pointer and the local index. More...
 
integer(i4b) function get_regional_offset (this, v_model)
 Get the offset for a regional model. More...
 
subroutine allocatescalars (this)
 Allocate scalar data. More...
 
subroutine getdiscretization (this, disu)
 Sets the discretization (DISU) after all preprocessing by this grid connection has been done,. More...
 
subroutine buildinterfacemap (this)
 Build interface map object for outside use. More...
 
subroutine destroy (this)
 Deallocate grid connection resources. More...
 
logical function isperiodic (this, n, m)
 Test if the connection between nodes within. More...
 

Variables

integer(i4b), parameter initnrneighbors = 7
 

Detailed Description

  • remove camelCase

Function/Subroutine Documentation

◆ addneighborcell()

subroutine gridconnectionmodule::addneighborcell ( class(gridconnectiontype), intent(in)  this,
type(cellwithnbrstype), intent(inout)  cellNbrs,
integer(i4b), intent(in)  newNbrIdx,
class(virtualmodeltype), pointer  v_nbr_model,
type(globalcelltype), optional  mask 
)
private
Parameters
[in]thisthis grid connection instance
[in,out]cellnbrsthe root cell which to add to
[in]newnbridxthe neighboring cell's index
v_nbr_modelthe model where the new neighbor lives
maskdon't add connections to this cell (optional)

Definition at line 465 of file GridConnection.f90.

466  class(GridConnectionType), intent(in) :: this !< this grid connection instance
467  type(CellWithNbrsType), intent(inout) :: cellNbrs !< the root cell which to add to
468  integer(I4B), intent(in) :: newNbrIdx !< the neighboring cell's index
469  class(VirtualModelType), pointer :: v_nbr_model !< the model where the new neighbor lives
470  type(GlobalCellType), optional :: mask !< don't add connections to this cell (optional)
471 
472  if (present(mask)) then
473  if (newnbridx == mask%index .and. mask%v_model == v_nbr_model) then
474  return
475  end if
476  end if
477 
478  call cellnbrs%addNbrCell(newnbridx, v_nbr_model)
479 

◆ addneighbors()

recursive subroutine gridconnectionmodule::addneighbors ( class(gridconnectiontype), intent(inout)  this,
type(cellwithnbrstype), intent(inout), target  cellNbrs,
integer(i4b), intent(inout)  depth,
type(globalcelltype), optional  mask,
logical(lgp)  interior 
)
private
Parameters
[in,out]thisthis grid connection
[in,out]cellnbrscell to add to
[in,out]depthcurrent depth (typically decreases in recursion)
maskmask to excluded back-and-forth connection between cells
interiorwhen true, we are adding from the exchange back into the model

Definition at line 368 of file GridConnection.f90.

369  use simmodule, only: ustop
370  class(GridConnectionType), intent(inout) :: this !< this grid connection
371  type(CellWithNbrsType), intent(inout), target :: cellNbrs !< cell to add to
372  integer(I4B), intent(inout) :: depth !< current depth (typically decreases in recursion)
373  type(GlobalCellType), optional :: mask !< mask to excluded back-and-forth connection between cells
374  logical(LGP) :: interior !< when true, we are adding from the exchange back into the model
375  ! local
376  type(GlobalCellType), pointer :: cell
377  integer(I4B) :: ipos, ipos_start, ipos_end
378  integer(I4B) :: nbrIdx, inbr
379  integer(I4B) :: newDepth
380 
381  ! readability
382  cell => cellnbrs%cell
383 
384  ! if depth == 1, then we are not adding neighbors but use
385  ! the boundary and connected cell only
386  if (depth < 2) then
387  return
388  end if
389  newdepth = depth - 1
390 
391  ! find neighbors local to this cell by looping through grid connections
392  ipos_start = cell%v_model%con_ia%get(cell%index) + 1
393  ipos_end = cell%v_model%con_ia%get(cell%index + 1) - 1
394  do ipos = ipos_start, ipos_end
395  nbridx = cell%v_model%con_ja%get(ipos)
396  call this%addNeighborCell(cellnbrs, nbridx, cellnbrs%cell%v_model, mask)
397  end do
398 
399  ! add remote nbr using the data from the exchanges
400  call this%addRemoteNeighbors(cellnbrs, mask)
401 
402  ! now find nbr-of-nbr
403  do inbr = 1, cellnbrs%nrOfNbrs
404 
405  ! are we leaving the model through another exchange?
406  if (interior .and. cellnbrs%cell%v_model == this%model) then
407  if (.not. cellnbrs%neighbors(inbr)%cell%v_model == this%model) then
408  ! decrement by 1, because the connection we are crossing is not
409  ! calculated by this interface
410  newdepth = newdepth - 1
411  end if
412  end if
413  ! and add neighbors with the new depth
414  call this%addNeighbors(cellnbrs%neighbors(inbr), newdepth, &
415  cellnbrs%cell, interior)
416  end do
417 
This module contains simulation methods.
Definition: Sim.f90:10
subroutine, public ustop(stopmess, ioutlocal)
Stop the simulation.
Definition: Sim.f90:315
Here is the call graph for this function:

◆ addremoteneighbors()

subroutine gridconnectionmodule::addremoteneighbors ( class(gridconnectiontype), intent(inout)  this,
type(cellwithnbrstype), intent(inout)  cellNbrs,
type(globalcelltype), optional  mask 
)
Parameters
[in,out]thisthis grid connection instance
[in,out]cellnbrscell to add to
maska mask to exclude back-and-forth connections

Definition at line 422 of file GridConnection.f90.

423  class(GridConnectionType), intent(inout) :: this !< this grid connection instance
424  type(CellWithNbrsType), intent(inout) :: cellNbrs !< cell to add to
425  type(GlobalCellType), optional :: mask !< a mask to exclude back-and-forth connections
426  ! local
427  integer(I4B) :: ix, iexg
428  class(VirtualExchangeType), pointer :: v_exchange
429  class(VirtualModelType), pointer :: v_m1, v_m2
430 
431  ! loop over all exchanges
432  do ix = 1, this%haloExchanges%size
433 
434  v_exchange => get_virtual_exchange(this%haloExchanges%at(ix))
435  v_m1 => v_exchange%v_model1
436  v_m2 => v_exchange%v_model2
437 
438  ! loop over n-m links in the exchange
439  if (cellnbrs%cell%v_model == v_m1) then
440  do iexg = 1, v_exchange%nexg%get()
441  if (v_exchange%nodem1%get(iexg) == cellnbrs%cell%index) then
442  ! we have a link, now add foreign neighbor
443  call this%addNeighborCell( &
444  cellnbrs, v_exchange%nodem2%get(iexg), v_m2, mask)
445  end if
446  end do
447  end if
448  ! and the reverse
449  if (cellnbrs%cell%v_model == v_m2) then
450  do iexg = 1, v_exchange%nexg%get()
451  if (v_exchange%nodem2%get(iexg) == cellnbrs%cell%index) then
452  ! we have a link, now add foreign neighbor
453  call this%addNeighborCell( &
454  cellnbrs, v_exchange%nodem1%get(iexg), v_m1, mask)
455  end if
456  end do
457  end if
458 
459  end do
460 
Here is the call graph for this function:

◆ addtoglobalmap()

subroutine gridconnectionmodule::addtoglobalmap ( class(gridconnectiontype), intent(inout)  this,
integer(i4b), intent(in)  ifaceIdx,
type(globalcelltype), intent(in)  cell 
)
private
Parameters
[in,out]thisthis grid connection instance
[in]ifaceidxunique idx in the interface grid
[in]cellthe global cell

Definition at line 511 of file GridConnection.f90.

512  class(GridConnectionType), intent(inout) :: this !< this grid connection instance
513  integer(I4B), intent(in) :: ifaceIdx !< unique idx in the interface grid
514  type(GlobalCellType), intent(in) :: cell !< the global cell
515  ! local
516  integer(I4B) :: i, currentSize, newSize
517  type(GlobalCellType), dimension(:), pointer :: tempMap
518 
519  ! inflate?
520  currentsize = size(this%idxToGlobal)
521  if (ifaceidx > currentsize) then
522  newsize = nint(1.5 * currentsize)
523  allocate (tempmap(newsize))
524  do i = 1, currentsize
525  tempmap(i) = this%idxToGlobal(i)
526  end do
527 
528  deallocate (this%idxToGlobal)
529  this%idxToGlobal => tempmap
530  end if
531 
532  this%idxToGlobal(ifaceidx) = cell
533 

◆ addtoregionalmodels()

subroutine gridconnectionmodule::addtoregionalmodels ( class(gridconnectiontype), intent(inout)  this,
class(virtualmodeltype), pointer  v_model 
)
private
Parameters
[in,out]thisthis grid connection
v_modelthe model to add to the region

Definition at line 216 of file GridConnection.f90.

217  class(GridConnectionType), intent(inout) :: this !< this grid connection
218  class(VirtualModelType), pointer :: v_model !< the model to add to the region
219  ! local
220  class(*), pointer :: vm_obj
221 
222  vm_obj => v_model
223  if (.not. this%regionalModels%ContainsObject(vm_obj)) then
224  call this%regionalModels%Add(vm_obj)
225  end if
226 

◆ allocatescalars()

subroutine gridconnectionmodule::allocatescalars ( class(gridconnectiontype this)
private
Parameters
thisthis grid connection instance

Definition at line 959 of file GridConnection.f90.

961  class(GridConnectionType) :: this !< this grid connection instance
962 
963  call mem_allocate(this%nrOfBoundaryCells, 'NRBNDCELLS', this%memoryPath)
964  call mem_allocate(this%indexCount, 'IDXCOUNT', this%memoryPath)
965  call mem_allocate(this%nrOfCells, 'NRCELLS', this%memoryPath)
966 

◆ buildconnections()

subroutine gridconnectionmodule::buildconnections ( class(gridconnectiontype), intent(inout)  this)
private
Parameters
[in,out]thisthis grid connection instance

Definition at line 286 of file GridConnection.f90.

287  class(GridConnectionType), intent(inout) :: this !< this grid connection instance
288  ! local
289  integer(I4B) :: icell, iconn
290  integer(I4B), dimension(:), allocatable :: nnz
291  type(SparseMatrix), pointer :: sparse
292  integer(I4B) :: ierror
293  type(ConnectionsType), pointer :: conn
294 
295  ! Recursively generate interface cell indices, fill map to global cells,
296  ! and add to region lookup table
297  this%indexCount = 0
298  do icell = 1, this%nrOfBoundaryCells
299  call this%registerInterfaceCells(this%boundaryCells(icell))
300  end do
301  do icell = 1, this%nrOfBoundaryCells
302  call this%registerInterfaceCells(this%connectedCells(icell))
303  end do
304  this%nrOfCells = this%indexCount
305 
306  ! compress lookup table
307  call this%compressGlobalMap()
308 
309  ! sort interface indexes such that 'n > m' means 'n below m'
310  call this%sortInterfaceGrid()
311 
312  ! allocate a map from interface index to global coordinates
313  call mem_allocate(this%idxToGlobalIdx, this%nrOfCells, &
314  'IDXTOGLOBALIDX', this%memoryPath)
315 
316  ! create sparse data structure, to temporarily hold connections
317  allocate (sparse)
318  allocate (nnz(this%nrOfCells))
319  nnz = initnrneighbors + 1
320  call sparse%init(this%nrOfCells, this%nrOfCells, nnz)
321 
322  ! now (recursively) add connections to sparse, start with
323  ! the primary connections (n-m from the exchange files)
324  call this%makePrimaryConnections(sparse)
325  ! then into own domain
326  do icell = 1, this%nrOfBoundaryCells
327  call this%connectNeighborCells(this%boundaryCells(icell), sparse)
328  end do
329  ! and same for the neighbors of connected cells
330  do icell = 1, this%nrOfBoundaryCells
331  call this%connectNeighborCells(this%connectedCells(icell), sparse)
332  end do
333 
334  ! create connections object
335  allocate (this%connections)
336  conn => this%connections
337  call conn%allocate_scalars(this%memoryPath)
338  conn%nodes = this%nrOfCells
339  conn%nja = sparse%nnz
340  conn%njas = (conn%nja - conn%nodes) / 2
341  call conn%allocate_arrays()
342  do iconn = 1, conn%njas
343  conn%anglex(iconn) = -999.
344  end do
345 
346  ! fill connection from sparse
347  call sparse%filliaja(conn%ia, conn%ja, ierror)
348  if (ierror /= 0) then
349  write (*, *) 'Error filling ia/ja in GridConnection: terminating...'
350  call ustop()
351  end if
352  call fillisym(conn%nodes, conn%nja, conn%ia, conn%ja, conn%isym)
353  call filljas(conn%nodes, conn%nja, conn%ia, conn%ja, conn%isym, conn%jas)
354  call sparse%destroy()
355 
356  ! fill connection data (ihc, cl1, cl2, etc.) using data
357  ! from models and exchanges
358  call this%fillConnectionDataInternal()
359  call this%fillConnectionDataFromExchanges()
360 
361  ! set the masks on connections
362  call this%createConnectionMask()
363 
Here is the call graph for this function:

◆ buildinterfacemap()

subroutine gridconnectionmodule::buildinterfacemap ( class(gridconnectiontype this)
Parameters
thisthis grid connection

Definition at line 1037 of file GridConnection.f90.

1039  use stlvecintmodule
1040  class(GridConnectionType) :: this !< this grid connection
1041  ! local
1042  integer(I4B) :: i, j, iloc, jloc
1043  integer(I4B) :: im, ix, mid, n
1044  integer(I4B) :: ipos, ipos_model
1045  type(STLVecInt) :: model_ids
1046  type(STLVecInt) :: src_idx_tmp, tgt_idx_tmp, sign_tmp
1047  class(VirtualExchangeType), pointer :: v_exg
1048  class(VirtualModelType), pointer :: vm
1049  class(VirtualModelType), pointer :: v_model1, v_model2
1050  type(InterfaceMapType), pointer :: imap
1051  integer(I4B), dimension(:), pointer, contiguous :: ia_ptr, ja_ptr
1052 
1053  allocate (this%interfaceMap)
1054  imap => this%interfaceMap
1055 
1056  ! first get the participating models
1057  call model_ids%init()
1058  do i = 1, this%nrOfCells
1059  call model_ids%push_back_unique(this%idxToGlobal(i)%v_model%id)
1060  end do
1061 
1062  ! initialize the map
1063  call imap%init(model_ids%size, this%haloExchanges%size)
1064 
1065  ! for each model part of this interface, ...
1066  do im = 1, model_ids%size
1067  mid = model_ids%at(im)
1068  imap%model_ids(im) = mid
1069  vm => get_virtual_model(mid)
1070  imap%model_names(im) = vm%name
1071  call src_idx_tmp%init()
1072  call tgt_idx_tmp%init()
1073 
1074  ! store the node map for this model
1075  do i = 1, this%nrOfCells
1076  if (mid == this%idxToGlobal(i)%v_model%id) then
1077  call src_idx_tmp%push_back(this%idxToGlobal(i)%index)
1078  call tgt_idx_tmp%push_back(i)
1079  end if
1080  end do
1081 
1082  ! and copy into interface map
1083  allocate (imap%node_maps(im)%src_idx(src_idx_tmp%size))
1084  allocate (imap%node_maps(im)%tgt_idx(tgt_idx_tmp%size))
1085  do i = 1, src_idx_tmp%size
1086  imap%node_maps(im)%src_idx(i) = src_idx_tmp%at(i)
1087  imap%node_maps(im)%tgt_idx(i) = tgt_idx_tmp%at(i)
1088  end do
1089 
1090  call src_idx_tmp%destroy()
1091  call tgt_idx_tmp%destroy()
1092 
1093  ! and for connections
1094  call src_idx_tmp%init()
1095  call tgt_idx_tmp%init()
1096 
1097  ! store the connection map for this model
1098  do i = 1, this%nrOfCells
1099  if (mid /= this%idxToGlobal(i)%v_model%id) cycle
1100  do ipos = this%connections%ia(i), this%connections%ia(i + 1) - 1
1101  j = this%connections%ja(ipos)
1102  if (mid /= this%idxToGlobal(j)%v_model%id) cycle
1103 
1104  ! i and j are now in same model (mid)
1105  iloc = this%idxToGlobal(i)%index
1106  jloc = this%idxToGlobal(j)%index
1107  ia_ptr => this%idxToGlobal(i)%v_model%con_ia%get_array()
1108  ja_ptr => this%idxToGlobal(i)%v_model%con_ja%get_array()
1109  ipos_model = getcsrindex(iloc, jloc, ia_ptr, ja_ptr)
1110  call src_idx_tmp%push_back(ipos_model)
1111  call tgt_idx_tmp%push_back(ipos)
1112  end do
1113  end do
1114 
1115  ! copy into interface map
1116  allocate (imap%conn_maps(im)%src_idx(src_idx_tmp%size))
1117  allocate (imap%conn_maps(im)%tgt_idx(tgt_idx_tmp%size))
1118  do i = 1, src_idx_tmp%size
1119  imap%conn_maps(im)%src_idx(i) = src_idx_tmp%at(i)
1120  imap%conn_maps(im)%tgt_idx(i) = tgt_idx_tmp%at(i)
1121  end do
1122 
1123  call src_idx_tmp%destroy()
1124  call tgt_idx_tmp%destroy()
1125 
1126  end do
1127 
1128  call model_ids%destroy()
1129 
1130  ! for each exchange that is part of this interface
1131  do ix = 1, this%haloExchanges%size
1132 
1133  ! all exchanges in this list should have at
1134  ! least one relevant connection for this map
1135  v_exg => get_virtual_exchange(this%haloExchanges%at(ix))
1136  v_model1 => v_exg%v_model1
1137  v_model2 => v_exg%v_model2
1138 
1139  imap%exchange_ids(ix) = v_exg%id
1140  imap%exchange_names(ix) = v_exg%name
1141 
1142  call src_idx_tmp%init()
1143  call tgt_idx_tmp%init()
1144  call sign_tmp%init()
1145 
1146  do n = 1, v_exg%nexg%get()
1147  i = this%getInterfaceIndex(v_exg%nodem1%get(n), v_model1)
1148  j = this%getInterfaceIndex(v_exg%nodem2%get(n), v_model2)
1149  if (i == -1 .or. j == -1) cycle ! not all exchange nodes are part of the interface
1150  ipos = this%connections%getjaindex(i, j)
1151  if (ipos == 0) then
1152  ! this can typically happen at corner points for a larger
1153  ! stencil (XT3D), when both i and j are included in the
1154  ! interface grid as leaf nodes, but their connection is not.
1155  ! (c.f. 'test_gwf_ifmod_mult_exg.py')
1156  cycle
1157  end if
1158  call src_idx_tmp%push_back(n)
1159  call tgt_idx_tmp%push_back(ipos)
1160  call sign_tmp%push_back(1)
1161 
1162  ! and the reverse connection:
1163  call src_idx_tmp%push_back(n)
1164  call tgt_idx_tmp%push_back(this%connections%isym(ipos))
1165  call sign_tmp%push_back(-1)
1166  end do
1167 
1168  allocate (imap%exchange_maps(ix)%src_idx(src_idx_tmp%size))
1169  allocate (imap%exchange_maps(ix)%tgt_idx(tgt_idx_tmp%size))
1170  allocate (imap%exchange_maps(ix)%sign(sign_tmp%size))
1171  do i = 1, src_idx_tmp%size
1172  imap%exchange_maps(ix)%src_idx(i) = src_idx_tmp%at(i)
1173  imap%exchange_maps(ix)%tgt_idx(i) = tgt_idx_tmp%at(i)
1174  imap%exchange_maps(ix)%sign(i) = sign_tmp%at(i)
1175  end do
1176 
1177  call src_idx_tmp%destroy()
1178  call tgt_idx_tmp%destroy()
1179  call sign_tmp%destroy()
1180 
1181  end do
1182 
1183  ! set the primary exchange idx
1184  ! findloc cannot be used until gfortran 9...
1185  imap%prim_exg_idx = -1
1186  do i = 1, imap%nr_exchanges
1187  if (imap%exchange_names(i) == this%primaryExchange%name) then
1188  imap%prim_exg_idx = i
1189  exit
1190  end if
1191  end do
1192 
1193  ! sanity check
1194  ! do i = 1, interfaceMap%nr_models
1195  ! if (size(interfaceMap%node_map(i)%src_idx) == 0) then
1196  ! write(*,*) 'Error: empty node map in interface for ', &
1197  ! this%primaryExchange%name
1198  ! call ustop()
1199  ! end if
1200  ! if (size(interfaceMap%connection_map(i)%src_idx) == 0) then
1201  ! write(*,*) 'Error: empty connection map in interface for ', &
1202  ! this%primaryExchange%name
1203  ! call ustop()
1204  ! end if
1205  ! end do
1206  ! do i = 1, interfaceMap%nr_exchanges
1207  ! if (size(interfaceMap%exchange_map(i)%src_idx) == 0) then
1208  ! write(*,*) 'Error: empty exchange map in interface for ', &
1209  ! this%primaryExchange%name
1210  ! call ustop()
1211  ! end if
1212  ! end do
1213 
class(basemodeltype) function, pointer, public getbasemodelfromlist(list, idx)
Definition: BaseModel.f90:172
Highest level model type. All models extend this parent type.
Definition: BaseModel.f90:13
Here is the call graph for this function:

◆ compressglobalmap()

subroutine gridconnectionmodule::compressglobalmap ( class(gridconnectiontype), intent(inout)  this)
private
Parameters
[in,out]thisthis grid connection instance

Definition at line 538 of file GridConnection.f90.

539  class(GridConnectionType), intent(inout) :: this !< this grid connection instance
540  ! local
541  type(GlobalCellType), dimension(:), pointer :: tempMap
542 
543  if (size(this%idxToGlobal) > this%nrOfCells) then
544  allocate (tempmap(this%nrOfCells))
545  tempmap(1:this%nrOfCells) = this%idxToGlobal(1:this%nrOfCells)
546  deallocate (this%idxToGlobal)
547  allocate (this%idxToGlobal(this%nrOfCells))
548  this%idxToGlobal(1:this%nrOfCells) = tempmap(1:this%nrOfCells)
549  deallocate (tempmap)
550  end if
551 

◆ connectcell()

subroutine gridconnectionmodule::connectcell ( class(gridconnectiontype), intent(in)  this,
integer(i4b)  idx1,
class(virtualmodeltype), pointer  v_model1,
integer(i4b)  idx2,
class(virtualmodeltype), pointer  v_model2 
)
private
Parameters
[in]thisthis grid connection
idx1local index cell 1
v_model1model of cell 1
idx2local index cell 2
v_model2model of cell 2

Definition at line 179 of file GridConnection.f90.

180  class(GridConnectionType), intent(in) :: this !< this grid connection
181  integer(I4B) :: idx1 !< local index cell 1
182  class(VirtualModelType), pointer :: v_model1 !< model of cell 1
183  integer(I4B) :: idx2 !< local index cell 2
184  class(VirtualModelType), pointer :: v_model2 !< model of cell 2
185  ! local
186  type(GlobalCellType), pointer :: bnd_cell, conn_cell
187 
188  this%nrOfBoundaryCells = this%nrOfBoundaryCells + 1
189  if (this%nrOfBoundaryCells > size(this%boundaryCells)) then
190  write (*, *) 'Error: nr of cell connections exceeds '// &
191  'capacity in grid connection, terminating...'
192  call ustop()
193  end if
194 
195  bnd_cell => this%boundaryCells(this%nrOfBoundaryCells)%cell
196  conn_cell => this%connectedCells(this%nrOfBoundaryCells)%cell
197  if (v_model1 == this%model) then
198  bnd_cell%index = idx1
199  bnd_cell%v_model => v_model1
200  conn_cell%index = idx2
201  conn_cell%v_model => v_model2
202  else if (v_model2 == this%model) then
203  bnd_cell%index = idx2
204  bnd_cell%v_model => v_model2
205  conn_cell%index = idx1
206  conn_cell%v_model => v_model1
207  else
208  write (*, *) 'Error: unable to connect cells outside the model'
209  call ustop()
210  end if
211 
Here is the call graph for this function:

◆ connectneighborcells()

recursive subroutine gridconnectionmodule::connectneighborcells ( class(gridconnectiontype), intent(inout)  this,
type(cellwithnbrstype cell,
type(sparsematrix), pointer  sparse 
)
private
Parameters
[in,out]thisthis grid connection instance
cellthe cell whose connections is to be added
sparsethe sparse data structure to hold the connections

Definition at line 631 of file GridConnection.f90.

632  class(GridConnectionType), intent(inout) :: this !< this grid connection instance
633  type(CellWithNbrsType) :: cell !< the cell whose connections is to be added
634  type(SparseMatrix), pointer :: sparse !< the sparse data structure to hold the connections
635  ! local
636  integer(I4B) :: ifaceIdx, ifaceIdxNbr ! unique idx in the interface grid
637  integer(I4B) :: inbr
638 
639  ifaceidx = this%getInterfaceIndex(cell%cell)
640  do inbr = 1, cell%nrOfNbrs
641  ifaceidxnbr = this%getInterfaceIndex(cell%neighbors(inbr)%cell)
642 
643  call sparse%addconnection(ifaceidxnbr, ifaceidxnbr, 1)
644  call sparse%addconnection(ifaceidx, ifaceidxnbr, 1)
645  call sparse%addconnection(ifaceidxnbr, ifaceidx, 1)
646 
647  ! recurse
648  call this%connectNeighborCells(cell%neighbors(inbr), sparse)
649  end do
650 

◆ connectprimaryexchange()

subroutine gridconnectionmodule::connectprimaryexchange ( class(gridconnectiontype this,
class(disconnexchangetype), pointer  primEx 
)
private
Parameters
thisthis grid connection
primexthe primary exchange for this connection

Definition at line 158 of file GridConnection.f90.

159  class(GridConnectionType) :: this !< this grid connection
160  class(DisConnExchangeType), pointer :: primEx !< the primary exchange for this connection
161  ! local
162  integer(I4B) :: iconn
163 
164  ! store the primary exchange
165  this%primaryExchange => primex
166 
167  ! connect the cells
168  do iconn = 1, primex%nexg
169  call this%connectCell(primex%nodem1(iconn), primex%v_model1, &
170  primex%nodem2(iconn), primex%v_model2)
171  end do
172 

◆ construct()

subroutine gridconnectionmodule::construct ( class(gridconnectiontype), intent(inout)  this,
class(numericalmodeltype), intent(in), pointer  model,
integer(i4b)  nrOfPrimaries,
character(len=*)  connectionName 
)

Definition at line 128 of file GridConnection.f90.

129  class(GridConnectionType), intent(inout) :: this !> this instance
130  class(NumericalModelType), pointer, intent(in) :: model !> the model for which the interface is constructed
131  integer(I4B) :: nrOfPrimaries !> the number of primary connections between the two models
132  character(len=*) :: connectionName !> the name, for memory management mostly
133  ! local
134  class(VirtualModelType), pointer :: v_model
135 
136  this%model => model
137  this%memoryPath = create_mem_path(connectionname, 'GC')
138 
139  call this%allocateScalars()
140 
141  allocate (this%boundaryCells(nrofprimaries))
142  allocate (this%connectedCells(nrofprimaries))
143  allocate (this%idxToGlobal(2 * nrofprimaries))
144 
145  v_model => get_virtual_model(model%id)
146  call this%addToRegionalModels(v_model)
147 
148  this%nrOfBoundaryCells = 0
149 
150  this%internalStencilDepth = 1
151  this%exchangeStencilDepth = 1
152  this%haloExchanges => null()
153 
Here is the call graph for this function:

◆ createconnectionmask()

subroutine gridconnectionmodule::createconnectionmask ( class(gridconnectiontype), intent(inout)  this)

The level indicates the nr of connections away from the remote neighbor, the diagonal term holds the negated value of their nearest connection. We end with setting

Parameters
[in,out]thisinstance of this grid connection

Definition at line 787 of file GridConnection.f90.

788  class(GridConnectionType), intent(inout) :: this !< instance of this grid connection
789  ! local
790  integer(I4B) :: icell, inbr, n, ipos
791  integer(I4B) :: level, newMask
792  type(CellWithNbrsType), pointer :: cell, nbrCell
793 
794  ! set all masks to zero to begin with
795  do ipos = 1, this%connections%nja
796  call this%connections%set_mask(ipos, 0)
797  end do
798 
799  ! remote connections remain masked
800  ! now set mask for exchange connections (level == 1)
801  level = 1
802  do icell = 1, this%nrOfBoundaryCells
803  call this%setMaskOnConnection(this%boundaryCells(icell), &
804  this%connectedCells(icell), level)
805  ! for cross-boundary connections, we need to apply the mask to both n-m and m-n,
806  ! because if the upper triangular one is disabled, its transposed (lower triangular)
807  ! counter part is skipped in the NPF calculation as well.
808  call this%setMaskOnConnection(this%connectedCells(icell), &
809  this%boundaryCells(icell), level)
810  end do
811 
812  ! now extend mask recursively into the internal domain (level > 1)
813  do icell = 1, this%nrOfBoundaryCells
814  cell => this%boundaryCells(icell)
815  do inbr = 1, cell%nrOfNbrs
816  nbrcell => this%boundaryCells(icell)%neighbors(inbr)
817  level = 2 ! this is incremented within the recursion
818  call this%maskInternalConnections(this%boundaryCells(icell), &
819  this%boundaryCells(icell)% &
820  neighbors(inbr), level)
821  end do
822  end do
823 
824  ! set normalized mask:
825  ! =1 for links with connectivity <= interior stencil depth
826  ! =0 otherwise
827  do n = 1, this%connections%nodes
828  ! set diagonals to zero
829  call this%connections%set_mask(this%connections%ia(n), 0)
830 
831  do ipos = this%connections%ia(n) + 1, this%connections%ia(n + 1) - 1
832  newmask = 0
833  if (this%connections%mask(ipos) > 0) then
834  if (this%connections%mask(ipos) < this%internalStencilDepth + 1) then
835  newmask = 1
836  end if
837  end if
838  ! set mask on off-diag
839  call this%connections%set_mask(ipos, newmask)
840  end do
841  end do
842 

◆ destroy()

subroutine gridconnectionmodule::destroy ( class(gridconnectiontype this)
Parameters
thisthis grid connection instance

Definition at line 1218 of file GridConnection.f90.

1220  class(GridConnectionType) :: this !< this grid connection instance
1221 
1222  call mem_deallocate(this%nrOfBoundaryCells)
1223  call mem_deallocate(this%indexCount)
1224  call mem_deallocate(this%nrOfCells)
1225 
1226  ! arrays
1227  deallocate (this%idxToGlobal)
1228  deallocate (this%boundaryCells)
1229  deallocate (this%connectedCells)
1230 
1231  call mem_deallocate(this%idxToGlobalIdx)
1232 

◆ extendconnection()

subroutine gridconnectionmodule::extendconnection ( class(gridconnectiontype), intent(inout)  this)
private

The following steps are taken:

  1. Recursively add interior neighbors (own model) up to the specified depth
  2. Recursively add exterior neighbors
  3. Allocate a (sparse) mapping table for the region
  4. Build connection object for the interface grid, and the mask
    Parameters
    [in,out]thisthis grid connection

Definition at line 238 of file GridConnection.f90.

239  class(GridConnectionType), intent(inout) :: this !< this grid connection
240  ! local
241  integer(I4B) :: remoteDepth, localDepth
242  integer(I4B) :: icell
243  integer(I4B) :: imod, regionSize, offset
244  class(VirtualModelType), pointer :: v_model
245  !integer(I4B), pointer :: nr_nodes
246 
247  ! we need (stencildepth-1) extra cells for the interior
248  remotedepth = this%exchangeStencilDepth
249  localdepth = 2 * this%internalStencilDepth - 1
250  if (localdepth < remotedepth) then
251  localdepth = remotedepth
252  end if
253 
254  ! first add the neighbors for the interior
255  ! (possibly extending into other models)
256  do icell = 1, this%nrOfBoundaryCells
257  call this%addNeighbors(this%boundaryCells(icell), localdepth, &
258  this%connectedCells(icell)%cell, .true.)
259  end do
260  ! and for the exterior
261  do icell = 1, this%nrOfBoundaryCells
262  call this%addNeighbors(this%connectedCells(icell), remotedepth, &
263  this%boundaryCells(icell)%cell, .false.)
264  end do
265 
266  ! set up mapping for the region (models participating in interface model grid)
267  allocate (this%regionalModelOffset(this%regionalModels%Count()))
268  regionsize = 0
269  offset = 0
270  do imod = 1, this%regionalModels%Count()
271  v_model => get_virtual_model_from_list(this%regionalModels, imod)
272  regionsize = regionsize + v_model%dis_nodes%get()
273  this%regionalModelOffset(imod) = offset
274  offset = offset + v_model%dis_nodes%get()
275  end do
276  ! init to -1, meaning 'interface index was not assigned yet'
277  allocate (this%region_to_iface_map(regionsize))
278  this%region_to_iface_map = -1
279 
280  call this%buildConnections()
281 
Here is the call graph for this function:

◆ fillconnectiondatafromexchanges()

subroutine gridconnectionmodule::fillconnectiondatafromexchanges ( class(gridconnectiontype), intent(inout)  this)
Parameters
[in,out]thisthis grid connection instance

Definition at line 713 of file GridConnection.f90.

714  use constantsmodule, only: dpio180
715  class(GridConnectionType), intent(inout) :: this !< this grid connection instance
716  ! local
717  integer(I4B) :: inx, iexg
718  integer(I4B) :: ipos, isym
719  integer(I4B) :: nOffset, mOffset, nIfaceIdx, mIfaceIdx
720  class(VirtualExchangeType), pointer :: v_exg
721  class(VirtualModelType), pointer :: v_m1, v_m2
722  type(ConnectionsType), pointer :: conn
723 
724  conn => this%connections
725 
726  do inx = 1, this%haloExchanges%size
727  v_exg => get_virtual_exchange(this%haloExchanges%at(inx))
728 
729  v_m1 => v_exg%v_model1
730  v_m2 => v_exg%v_model2
731 
732  if (v_exg%ianglex%get() > 0) then
733  conn%ianglex = 1
734  end if
735 
736  noffset = this%get_regional_offset(v_m1)
737  moffset = this%get_regional_offset(v_m2)
738  do iexg = 1, v_exg%nexg%get()
739  nifaceidx = this%region_to_iface_map(noffset + v_exg%nodem1%get(iexg))
740  mifaceidx = this%region_to_iface_map(moffset + v_exg%nodem2%get(iexg))
741  ! not all nodes from the exchanges are part of the interface grid
742  ! (think of exchanges between neighboring models, and their neighbors)
743  if (nifaceidx == -1 .or. mifaceidx == -1) then
744  cycle
745  end if
746 
747  ipos = conn%getjaindex(nifaceidx, mifaceidx)
748  ! (see prev. remark) sometimes the cells are in the interface grid,
749  ! but the connection isn't. This can happen for leaf nodes of the grid.
750  if (ipos == 0) then
751  ! no match, safely cycle
752  cycle
753  end if
754  isym = conn%jas(ipos)
755 
756  ! note: cl1 equals L_nm: the length from cell n to the shared
757  ! face with cell m (and cl2 analogously for L_mn)
758  if (nifaceidx < mifaceidx) then
759  conn%cl1(isym) = v_exg%cl1%get(iexg)
760  conn%cl2(isym) = v_exg%cl2%get(iexg)
761  if (v_exg%ianglex%get() > 0) then
762  conn%anglex(isym) = &
763  v_exg%auxvar%get(v_exg%ianglex%get(), iexg) * dpio180
764  end if
765  else
766  conn%cl1(isym) = v_exg%cl2%get(iexg)
767  conn%cl2(isym) = v_exg%cl1%get(iexg)
768  if (v_exg%ianglex%get() > 0) then
769  conn%anglex(isym) = mod(v_exg%auxvar%get(v_exg%ianglex%get(), iexg) &
770  + 180.0_dp, 360.0_dp) * dpio180
771  end if
772  end if
773  conn%hwva(isym) = v_exg%hwva%get(iexg)
774  conn%ihc(isym) = v_exg%ihc%get(iexg)
775 
776  end do
777  end do
778 
This module contains simulation constants.
Definition: Constants.f90:9
real(dp), parameter dpio180
real constant
Definition: Constants.f90:129
Here is the call graph for this function:

◆ fillconnectiondatainternal()

subroutine gridconnectionmodule::fillconnectiondatainternal ( class(gridconnectiontype), intent(inout)  this)
private
Parameters
[in,out]thisthis grid connection instance

Definition at line 655 of file GridConnection.f90.

656  use constantsmodule, only: dpi, dtwopi
657  class(GridConnectionType), intent(inout) :: this !< this grid connection instance
658  ! local
659  type(ConnectionsType), pointer :: conn
660  integer(I4B) :: n, m, ipos, isym, ipos_orig, isym_orig
661  type(GlobalCellType), pointer :: ncell, mcell
662  class(VirtualModelType), pointer :: v_m !< pointer to virtual model (readability)
663 
664  conn => this%connections
665 
666  do n = 1, conn%nodes
667  do ipos = conn%ia(n) + 1, conn%ia(n + 1) - 1
668  m = conn%ja(ipos)
669  if (n > m) cycle
670 
671  isym = conn%jas(ipos)
672  ncell => this%idxToGlobal(n)
673  mcell => this%idxToGlobal(m)
674  if (ncell%v_model == mcell%v_model) then
675 
676  ! for readability
677  v_m => ncell%v_model
678 
679  ! within same model, straight copy
680  ipos_orig = getcsrindex(ncell%index, mcell%index, &
681  v_m%con_ia%get_array(), v_m%con_ja%get_array())
682 
683  if (ipos_orig == 0) then
684  ! periodic boundary conditions can add connections between cells in
685  ! the same model, but they are dealt with through the exchange data
686  if (this%isPeriodic(ncell%index, mcell%index)) cycle
687 
688  ! this should not be possible
689  write (*, *) 'Error: cannot find cell connection in model grid'
690  call ustop()
691  end if
692 
693  isym_orig = v_m%con_jas%get(ipos_orig)
694  conn%hwva(isym) = v_m%con_hwva%get(isym_orig)
695  conn%ihc(isym) = v_m%con_ihc%get(isym_orig)
696  if (ncell%index < mcell%index) then
697  conn%cl1(isym) = v_m%con_cl1%get(isym_orig)
698  conn%cl2(isym) = v_m%con_cl2%get(isym_orig)
699  conn%anglex(isym) = v_m%con_anglex%get(isym_orig)
700  else
701  conn%cl1(isym) = v_m%con_cl2%get(isym_orig)
702  conn%cl2(isym) = v_m%con_cl1%get(isym_orig)
703  conn%anglex(isym) = mod(v_m%con_anglex%get(isym_orig) + dpi, dtwopi)
704  end if
705  end if
706  end do
707  end do
708 
real(dp), parameter dtwopi
real constant
Definition: Constants.f90:128
real(dp), parameter dpi
real constant
Definition: Constants.f90:127
Here is the call graph for this function:

◆ get_regional_offset()

integer(i4b) function gridconnectionmodule::get_regional_offset ( class(gridconnectiontype), intent(inout)  this,
class(virtualmodeltype), pointer  v_model 
)
private
Parameters
[in,out]thisthis grid connection instance
v_modelthe model to get the offset for
Returns
the index offset in the regional domain

Definition at line 938 of file GridConnection.f90.

939  class(GridConnectionType), intent(inout) :: this !< this grid connection instance
940  class(VirtualModelType), pointer :: v_model !< the model to get the offset for
941  integer(I4B) :: offset !< the index offset in the regional domain
942  ! local
943  integer(I4B) :: im
944  class(VirtualModelType), pointer :: vm
945 
946  offset = 0
947  do im = 1, this%regionalModels%Count()
948  vm => get_virtual_model_from_list(this%regionalModels, im)
949  if (vm == v_model) then
950  offset = this%regionalModelOffset(im)
951  return
952  end if
953  end do
954 
Here is the call graph for this function:

◆ getdiscretization()

subroutine gridconnectionmodule::getdiscretization ( class(gridconnectiontype this,
class(disutype), pointer  disu 
)
Parameters
thisthe grid connection
disuthe target disu object

Definition at line 972 of file GridConnection.f90.

974  use sparsemodule, only: sparsematrix
975  class(GridConnectionType) :: this !< the grid connection
976  class(DisuType), pointer :: disu !< the target disu object
977  ! local
978  integer(I4B) :: icell, nrOfCells, idx
979  class(VirtualModelType), pointer :: v_model
980  real(DP) :: xglo, yglo
981 
982  ! the following is similar to dis_df
983  nrofcells = this%nrOfCells
984  disu%nodes = nrofcells
985  disu%nodesuser = nrofcells
986  disu%nja = this%connections%nja
987 
988  call disu%allocate_arrays()
989  ! these are otherwise allocated in dis%read_dimensions
990  call disu%allocate_arrays_mem()
991 
992  ! fill data
993  do icell = 1, nrofcells
994  idx = this%idxToGlobal(icell)%index
995  disu%top(icell) = -huge(1.0_dp)
996  disu%bot(icell) = -huge(1.0_dp)
997  disu%area(icell) = -huge(1.0_dp)
998  end do
999 
1000  ! grid connections follow from GridConnection:
1001  disu%con => this%connections
1002  disu%njas = disu%con%njas
1003 
1004  ! copy cell x,y
1005  do icell = 1, nrofcells
1006  idx = this%idxToGlobal(icell)%index
1007  v_model => this%idxToGlobal(icell)%v_model
1008 
1009  ! we are merging grids with possibly (likely) different origins,
1010  ! transform to global coordinates:
1011  call dis_transform_xy(v_model%dis_xc%get(idx), &
1012  v_model%dis_yc%get(idx), &
1013  v_model%dis_xorigin%get(), &
1014  v_model%dis_yorigin%get(), &
1015  v_model%dis_angrot%get(), &
1016  xglo, yglo)
1017 
1018  ! NB: usernodes equals internal nodes for interface
1019  disu%cellxy(1, icell) = xglo
1020  disu%xc(icell) = xglo
1021  disu%cellxy(2, icell) = yglo
1022  disu%yc(icell) = yglo
1023  end do
1024 
1025  ! if vertices will be needed, it will look like this:
1026  !
1027  ! 1. determine total nr. of verts
1028  ! 2. allocate vertices list
1029  ! 3. create sparse
1030  ! 4. get vertex data per cell, add functions to base
1031  ! 5. add vertex (x,y) to list and connectivity to sparse
1032  ! 6. generate ia/ja from sparse
1033 
Here is the call graph for this function:

◆ getinterfaceindexbycell()

integer(i4b) function gridconnectionmodule::getinterfaceindexbycell ( class(gridconnectiontype), intent(inout)  this,
type(globalcelltype), intent(in)  cell 
)
private
Parameters
[in,out]thisthis grid connection instance
[in]cellthe global cell to get the interface index for
Returns
the index in the interface model

Definition at line 907 of file GridConnection.f90.

908  class(GridConnectionType), intent(inout) :: this !< this grid connection instance
909  type(GlobalCellType), intent(in) :: cell !< the global cell to get the interface index for
910  integer(I4B) :: iface_idx !< the index in the interface model
911  ! local
912  integer(I4B) :: offset, region_idx
913 
914  offset = this%get_regional_offset(cell%v_model)
915  region_idx = offset + cell%index
916  iface_idx = this%region_to_iface_map(region_idx)
917 
Here is the caller graph for this function:

◆ getinterfaceindexbyindexmodel()

integer(i4b) function gridconnectionmodule::getinterfaceindexbyindexmodel ( class(gridconnectiontype), intent(inout)  this,
integer(i4b)  index,
class(virtualmodeltype), pointer  v_model 
)
private
Parameters
[in,out]thisthis grid connection instance
indexthe local cell index
v_modelthe cell's model
Returns
the index in the interface model

Definition at line 922 of file GridConnection.f90.

923  class(GridConnectionType), intent(inout) :: this !< this grid connection instance
924  integer(I4B) :: index !< the local cell index
925  class(VirtualModelType), pointer :: v_model !< the cell's model
926  integer(I4B) :: iface_idx !< the index in the interface model
927  ! local
928  integer(I4B) :: offset, region_idx
929 
930  offset = this%get_regional_offset(v_model)
931  region_idx = offset + index
932  iface_idx = this%region_to_iface_map(region_idx)
933 
Here is the caller graph for this function:

◆ isperiodic()

logical function gridconnectionmodule::isperiodic ( class(gridconnectiontype), intent(in)  this,
integer(i4b), intent(in)  n,
integer(i4b), intent(in)  m 
)
Parameters
[in]thisthis grid connection instance
[in]nfirst node of the connection
[in]msecond node of the connection
Returns
true when periodic

Definition at line 1237 of file GridConnection.f90.

1238  class(GridConnectionType), intent(in) :: this !< this grid connection instance
1239  integer(I4B), intent(in) :: n !< first node of the connection
1240  integer(I4B), intent(in) :: m !< second node of the connection
1241  logical :: periodic !< true when periodic
1242  ! local
1243  integer(I4B) :: icell
1244 
1245  periodic = .false.
1246  do icell = 1, this%nrOfBoundaryCells
1247  if (.not. this%boundaryCells(icell)%cell%v_model == &
1248  this%connectedCells(icell)%cell%v_model) then
1249  cycle
1250  end if
1251 
1252  ! one way
1253  if (this%boundaryCells(icell)%cell%index == n) then
1254  if (this%connectedCells(icell)%cell%index == m) then
1255  periodic = .true.
1256  return
1257  end if
1258  end if
1259  ! or the other
1260  if (this%boundaryCells(icell)%cell%index == m) then
1261  if (this%connectedCells(icell)%cell%index == n) then
1262  periodic = .true.
1263  return
1264  end if
1265  end if
1266 
1267  end do
1268 

◆ makeprimaryconnections()

subroutine gridconnectionmodule::makeprimaryconnections ( class(gridconnectiontype), intent(inout)  this,
type(sparsematrix), pointer  sparse 
)
Parameters
[in,out]thisthis grid connection instance
sparsethe sparse data structure to hold the connections

Definition at line 606 of file GridConnection.f90.

607  class(GridConnectionType), intent(inout) :: this !< this grid connection instance
608  type(SparseMatrix), pointer :: sparse !< the sparse data structure to hold the connections
609  ! local
610  integer(I4B) :: icell
611  integer(I4B) :: ifaceIdx, ifaceIdxNbr
612 
613  do icell = 1, this%nrOfBoundaryCells
614  ifaceidx = this%getInterfaceIndex(this%boundaryCells(icell)%cell)
615  ifaceidxnbr = this%getInterfaceIndex(this%connectedCells(icell)%cell)
616 
617  ! add diagonals to sparse
618  call sparse%addconnection(ifaceidx, ifaceidx, 1)
619  call sparse%addconnection(ifaceidxnbr, ifaceidxnbr, 1)
620 
621  ! and cross terms
622  call sparse%addconnection(ifaceidx, ifaceidxnbr, 1)
623  call sparse%addconnection(ifaceidxnbr, ifaceidx, 1)
624  end do
625 

◆ maskinternalconnections()

recursive subroutine gridconnectionmodule::maskinternalconnections ( class(gridconnectiontype), intent(inout)  this,
type(cellwithnbrstype), intent(inout)  cell,
type(cellwithnbrstype), intent(inout)  nbrCell,
integer(i4b), intent(in)  level 
)
private
Parameters
[in,out]thisthis grid connection instance
[in,out]cellcell 1 in the connection to mask
[in,out]nbrcellcell 2 in the connection to mask

Definition at line 847 of file GridConnection.f90.

848  class(GridConnectionType), intent(inout) :: this !< this grid connection instance
849  type(CellWithNbrsType), intent(inout) :: cell !< cell 1 in the connection to mask
850  type(CellWithNbrsType), intent(inout) :: nbrCell !< cell 2 in the connection to mask
851  integer(I4B), intent(in) :: level
852  ! local
853  integer(I4B) :: inbr, newLevel
854 
855  ! only set the mask for internal connections, leaving the
856  ! others at 0
857  if (cell%cell%v_model == this%model .and. &
858  nbrcell%cell%v_model == this%model) then
859  ! this will set a mask on both diagonal, and both cross terms
860  call this%setMaskOnConnection(cell, nbrcell, level)
861  call this%setMaskOnConnection(nbrcell, cell, level)
862  end if
863 
864  ! recurse on nbrs-of-nbrs
865  newlevel = level + 1
866  do inbr = 1, nbrcell%nrOfNbrs
867  call this%maskInternalConnections(nbrcell, &
868  nbrcell%neighbors(inbr), &
869  newlevel)
870  end do
871 

◆ registerinterfacecells()

recursive subroutine gridconnectionmodule::registerinterfacecells ( class(gridconnectiontype), intent(inout)  this,
type(cellwithnbrstype cellWithNbrs 
)
private
Parameters
[in,out]thisthis grid connection instance
cellwithnbrsthe cell from where to start registering neighbors

Definition at line 484 of file GridConnection.f90.

485  class(GridConnectionType), intent(inout) :: this !< this grid connection instance
486  type(CellWithNbrsType) :: cellWithNbrs !< the cell from where to start registering neighbors
487  ! local
488  integer(I4B) :: offset, inbr
489  integer(I4B) :: regionIdx ! unique idx in the region (all connected models)
490  integer(I4B) :: ifaceIdx ! unique idx in the interface grid
491 
492  offset = this%get_regional_offset(cellwithnbrs%cell%v_model)
493  regionidx = offset + cellwithnbrs%cell%index
494  ifaceidx = this%getInterfaceIndex(cellwithnbrs%cell)
495  if (ifaceidx == -1) then
496  this%indexCount = this%indexCount + 1
497  ifaceidx = this%indexCount
498  call this%addToGlobalMap(ifaceidx, cellwithnbrs%cell)
499  this%region_to_iface_map(regionidx) = ifaceidx
500  end if
501 
502  ! and also for its neighbors
503  do inbr = 1, cellwithnbrs%nrOfNbrs
504  call this%registerInterfaceCells(cellwithnbrs%neighbors(inbr))
505  end do
506 

◆ setmaskonconnection()

subroutine gridconnectionmodule::setmaskonconnection ( class(gridconnectiontype), intent(inout)  this,
type(cellwithnbrstype), intent(inout)  cell,
type(cellwithnbrstype), intent(inout)  nbrCell,
integer(i4b), intent(in)  level 
)
private
Parameters
[in,out]thisthis grid connection instance
[in,out]cellcell 1 in the connection
[in,out]nbrcellcell 2 in the connection
[in]levelthe level value to set the mask to

Definition at line 877 of file GridConnection.f90.

878  class(GridConnectionType), intent(inout) :: this !< this grid connection instance
879  type(CellWithNbrsType), intent(inout) :: cell !< cell 1 in the connection
880  type(CellWithNbrsType), intent(inout) :: nbrCell !< cell 2 in the connection
881  integer(I4B), intent(in) :: level !< the level value to set the mask to
882  ! local
883  integer(I4B) :: ifaceIdx, ifaceIdxNbr
884  integer(I4B) :: iposdiag, ipos
885  integer(I4B) :: currentLevel
886 
887  ifaceidx = this%getInterfaceIndex(cell%cell)
888  ifaceidxnbr = this%getInterfaceIndex(nbrcell%cell)
889 
890  ! diagonal
891  iposdiag = this%connections%getjaindex(ifaceidx, ifaceidx)
892  currentlevel = this%connections%mask(iposdiag)
893  if (currentlevel == 0 .or. level < currentlevel) then
894  call this%connections%set_mask(iposdiag, level)
895  end if
896  ! cross term
897  ipos = this%connections%getjaindex(ifaceidx, ifaceidxnbr)
898  currentlevel = this%connections%mask(ipos)
899  if (currentlevel == 0 .or. level < currentlevel) then
900  call this%connections%set_mask(ipos, level)
901  end if
902 

◆ sortinterfacegrid()

subroutine gridconnectionmodule::sortinterfacegrid ( class(gridconnectiontype), intent(inout)  this)
private
Parameters
[in,out]thisthis grid connection instance

Definition at line 556 of file GridConnection.f90.

557  use gridsorting, only: quicksortgrid
558  class(GridConnectionType), intent(inout) :: this !< this grid connection instance
559  ! local
560  integer(I4B), dimension(:), allocatable :: newToOldIdx
561  integer(I4B), dimension(:), allocatable :: oldToNewIdx
562  integer(I4B) :: idxOld
563  integer(I4B) :: i
564  type(GlobalCellType), dimension(:), allocatable :: sortedGlobalMap
565  integer(I4B), dimension(:), allocatable :: sortedRegionMap
566 
567  ! sort based on coordinates
568  newtooldidx = (/(i, i=1, size(this%idxToGlobal))/)
569  call quicksortgrid(newtooldidx, size(newtooldidx), this%idxToGlobal)
570 
571  ! and invert
572  allocate (oldtonewidx(size(newtooldidx)))
573  do i = 1, size(oldtonewidx)
574  oldtonewidx(newtooldidx(i)) = i
575  end do
576 
577  ! reorder global table
578  allocate (sortedglobalmap(size(this%idxToGlobal)))
579  do i = 1, size(newtooldidx)
580  sortedglobalmap(i) = this%idxToGlobal(newtooldidx(i))
581  end do
582  do i = 1, size(newtooldidx)
583  this%idxToGlobal(i) = sortedglobalmap(i)
584  end do
585  deallocate (sortedglobalmap)
586 
587  ! reorder regional lookup table
588  allocate (sortedregionmap(size(this%region_to_iface_map)))
589  do i = 1, size(sortedregionmap)
590  if (this%region_to_iface_map(i) /= -1) then
591  idxold = this%region_to_iface_map(i)
592  sortedregionmap(i) = oldtonewidx(idxold)
593  else
594  sortedregionmap(i) = -1
595  end if
596  end do
597  do i = 1, size(sortedregionmap)
598  this%region_to_iface_map(i) = sortedregionmap(i)
599  end do
600  deallocate (sortedregionmap)
601 
subroutine, public quicksortgrid(array, arraySize, idxToGlobal)
Definition: GridSorting.f90:15
Here is the call graph for this function:

Variable Documentation

◆ initnrneighbors

integer(i4b), parameter gridconnectionmodule::initnrneighbors = 7
private

Definition at line 30 of file GridConnection.f90.

30  integer(I4B), parameter :: InitNrNeighbors = 7