42 integer(I4B),
pointer :: nr_connections => null()
45 logical(LGP) :: owns_exchange
49 integer(I4B),
pointer :: int_stencil_depth => null()
51 integer(I4B),
pointer :: exg_stencil_depth => null()
55 integer(I4B),
pointer :: neq => null()
57 real(dp),
dimension(:),
pointer,
contiguous :: rhs => null()
58 real(dp),
dimension(:),
pointer,
contiguous :: x => null()
59 integer(I4B),
dimension(:),
pointer,
contiguous :: active => null()
63 integer(I4B),
dimension(:),
pointer :: ipos_to_sln => null()
76 procedure :: exg_ac => spatialcon_ac
77 procedure :: exg_mc => spatialcon_mc
78 procedure :: exg_cf => spatialcon_cf
79 procedure :: exg_fc => spatialcon_fc
80 procedure :: exg_da => spatialcon_da
85 procedure, pass(this) :: spatialcon_ac
86 procedure, pass(this) :: spatialcon_cf
87 procedure, pass(this) :: spatialcon_fc
88 procedure, pass(this) :: spatialcon_da
96 procedure,
private, pass(this) :: setupgridconnection
97 procedure,
private, pass(this) :: getnrofconnections
98 procedure,
private, pass(this) :: allocatescalars
99 procedure,
private, pass(this) :: allocatearrays
117 character(len=*),
intent(in) :: name
123 this%prim_exchange => exchange
125 allocate (this%ig_builder)
126 allocate (this%halo_models)
127 allocate (this%halo_exchanges)
128 allocate (this%matrix)
129 call this%allocateScalars()
131 this%int_stencil_depth = 1
132 this%exg_stencil_depth = 1
133 this%nr_connections = 0
136 this%interface_model => null()
145 call this%halo_models%init()
146 call this%halo_exchanges%init()
149 this%exg_stencil_depth, .true.)
157 depth, is_root, mask)
160 integer(I4B) :: model_id
162 integer(I4B),
value :: depth
163 logical(LGP) :: is_root
164 integer(I4B),
optional :: mask
168 integer(I4B) :: neighbor_id
169 integer(I4B) :: model_mask
173 if (.not.
present(mask))
then
179 call models_at_depth%init()
183 call models_at_depth%push_back_unique(model_id)
186 if (this%prim_exchange%v_model1%id == this%owner%id)
then
187 neighbor_id = this%prim_exchange%v_model2%id
189 neighbor_id = this%prim_exchange%v_model1%id
192 call models_at_depth%push_back_unique(neighbor_id)
193 call this%halo_models%push_back_unique(neighbor_id)
194 call this%halo_exchanges%push_back_unique(this%prim_exchange%id)
198 do i = 1, virtual_exchanges%Count()
200 v_exg => get_virtual_exchange_from_list(virtual_exchanges, i)
201 if (v_exg%v_model1%id == model_id)
then
202 neighbor_id = v_exg%v_model2%id
203 else if (v_exg%v_model2%id == model_id)
then
204 neighbor_id = v_exg%v_model1%id
209 if (neighbor_id > 0)
then
211 if (neighbor_id == model_mask) cycle
212 call models_at_depth%push_back_unique(neighbor_id)
213 call this%halo_models%push_back_unique(neighbor_id)
214 call this%halo_exchanges%push_back_unique(v_exg%id)
222 call models_at_depth%destroy()
227 do n = 1, models_at_depth%size
228 call this%addModelNeighbors(models_at_depth%at(n), virtual_exchanges, &
229 depth, .false., model_id)
233 call models_at_depth%destroy()
247 this%nr_connections = this%getNrOfConnections()
248 call this%ig_builder%construct(this%owner, &
249 this%nr_connections, &
251 this%ig_builder%internalStencilDepth = this%int_stencil_depth
252 this%ig_builder%exchangeStencilDepth = this%exg_stencil_depth
253 this%ig_builder%haloExchanges => this%halo_exchanges
254 do i = 1, this%halo_models%size
256 call this%ig_builder%addToRegionalModels(v_model)
258 call this%setupGridConnection()
260 this%neq = this%ig_builder%nrOfCells
261 call this%allocateArrays()
270 integer(I4B) :: iface_idx, glob_idx
275 gc => this%ig_builder
276 do iface_idx = 1, gc%nrOfCells
277 glob_idx = gc%idxToGlobal(iface_idx)%index + &
278 gc%idxToGlobal(iface_idx)%v_model%moffset%get()
279 gc%idxToGlobalIdx(iface_idx) = glob_idx
290 this%interface_model%x => this%x
292 this%interface_model%memoryPath,
'X', &
294 this%interface_model%rhs => this%rhs
295 call mem_checkin(this%interface_model%rhs,
'RHS', &
296 this%interface_model%memoryPath,
'RHS', &
298 this%interface_model%ibound => this%active
299 call mem_checkin(this%interface_model%ibound,
'IBOUND', &
300 this%interface_model%memoryPath,
'IBOUND', &
313 call sparse%init(this%neq, this%neq, 7)
314 call this%interface_model%model_ac(sparse)
317 call this%createCoefficientMatrix(sparse)
318 call sparse%destroy()
321 matrix_base => this%matrix
322 call this%interface_model%model_mc(matrix_base)
323 call this%maskOwnerConnections()
336 integer(I4B) :: ipos, n, m, nloc, mloc, csr_idx
340 conn => this%interface_model%dis%con
343 if (.not. this%ig_builder%idxToGlobal(n)%v_model == this%owner)
then
346 nloc = this%ig_builder%idxToGlobal(n)%index
348 do ipos = conn%ia(n) + 1, conn%ia(n + 1) - 1
350 if (.not. this%ig_builder%idxToGlobal(m)%v_model == this%owner)
then
353 mloc = this%ig_builder%idxToGlobal(m)%index
355 if (conn%mask(ipos) > 0)
then
357 csr_idx =
getcsrindex(nloc, mloc, this%owner%ia, this%owner%ja)
358 if (csr_idx == -1)
then
361 if (this%ig_builder%isPeriodic(nloc, mloc)) cycle
363 write (*, *)
'Error: cannot find cell connection in global system'
367 if (this%owner%dis%con%mask(csr_idx) > 0)
then
368 call this%owner%dis%con%set_mask(csr_idx, 0)
374 call conn%set_mask(ipos, 0)
384 subroutine spatialcon_ac(this, sparse)
388 integer(I4B) :: n, m, ipos
389 integer(I4B) :: icol_start, icol_end
390 integer(I4B) :: nglo, mglo
393 if (.not. this%ig_builder%idxToGlobal(n)%v_model == this%owner)
then
398 nglo = this%ig_builder%idxToGlobal(n)%index + &
399 this%ig_builder%idxToGlobal(n)%v_model%moffset%get()
401 icol_start = this%matrix%get_first_col_pos(n)
402 icol_end = this%matrix%get_last_col_pos(n)
403 do ipos = icol_start, icol_end
404 m = this%matrix%get_column(ipos)
406 mglo = this%ig_builder%idxToGlobal(m)%index + &
407 this%ig_builder%idxToGlobal(m)%v_model%moffset%get()
408 call sparse%addconnection(nglo, mglo, 1)
413 end subroutine spatialcon_ac
417 subroutine spatialcon_mc(this, matrix_sln)
422 integer(I4B) :: i, m, n, mglo, nglo, ipos, ipos_sln
423 logical(LGP) :: is_owned
425 allocate (this%ipos_to_sln(this%matrix%nja))
426 do i = 1, this%matrix%nja
427 this%ipos_to_sln(i) = -1
431 is_owned = (this%ig_builder%idxToGlobal(n)%v_model == this%owner)
432 if (.not. is_owned) cycle
434 do ipos = this%matrix%ia(n), this%matrix%ia(n + 1) - 1
435 m = this%matrix%ja(ipos)
436 nglo = this%ig_builder%idxToGlobal(n)%index + &
437 this%ig_builder%idxToGlobal(n)%v_model%moffset%get()
438 mglo = this%ig_builder%idxToGlobal(m)%index + &
439 this%ig_builder%idxToGlobal(m)%v_model%moffset%get()
441 ipos_sln = matrix_sln%get_position(nglo, mglo)
442 if (ipos_sln == -1)
then
444 write (*, *)
'Error: cannot find cell connection in global system'
447 this%ipos_to_sln(ipos) = ipos_sln
452 end subroutine spatialcon_mc
457 subroutine spatialcon_cf(this, kiter)
459 integer(I4B),
intent(in) :: kiter
464 call this%matrix%zero_entries()
470 call this%interface_model%model_cf(kiter)
472 end subroutine spatialcon_cf
476 subroutine spatialcon_fc(this, kiter, matrix_sln, rhs_sln, inwtflag)
478 integer(I4B),
intent(in) :: kiter
480 real(DP),
dimension(:),
intent(inout) :: rhs_sln
481 integer(I4B),
optional,
intent(in) :: inwtflag
483 integer(I4B) :: n, nglo
484 integer(I4B) :: icol_start, icol_end, ipos
487 matrix_base => this%matrix
488 call this%interface_model%model_fc(kiter, matrix_base, inwtflag)
494 if (.not. this%ig_builder%idxToGlobal(n)%v_model == this%owner)
then
498 nglo = this%ig_builder%idxToGlobal(n)%index + &
499 this%ig_builder%idxToGlobal(n)%v_model%moffset%get() - &
500 matrix_sln%get_row_offset()
501 rhs_sln(nglo) = rhs_sln(nglo) + this%rhs(n)
503 icol_start = this%matrix%get_first_col_pos(n)
504 icol_end = this%matrix%get_last_col_pos(n)
505 do ipos = icol_start, icol_end
506 call matrix_sln%add_value_pos(this%ipos_to_sln(ipos), &
507 this%matrix%get_value_pos(ipos))
511 end subroutine spatialcon_fc
515 subroutine spatialcon_da(this)
527 call this%halo_models%destroy()
528 call this%halo_exchanges%destroy()
529 deallocate (this%halo_models)
530 deallocate (this%halo_exchanges)
531 call this%matrix%destroy()
532 deallocate (this%matrix)
534 call this%ig_builder%destroy()
535 call this%iface_dist_vars%Clear(
destroy=.true.)
536 deallocate (this%ig_builder)
537 deallocate (this%interface_map)
538 deallocate (this%ipos_to_sln)
540 end subroutine spatialcon_da
547 subroutine setupgridconnection(this)
552 call this%ig_builder%connectPrimaryExchange(this%prim_exchange)
555 call this%ig_builder%extendConnection()
558 call this%ig_builder%buildInterfaceMap()
559 this%interface_map => this%ig_builder%interfaceMap
561 end subroutine setupgridconnection
565 subroutine allocatescalars(this)
570 call mem_allocate(this%int_stencil_depth,
'INTSTDEPTH', this%memoryPath)
571 call mem_allocate(this%exg_stencil_depth,
'EXGSTDEPTH', this%memoryPath)
572 call mem_allocate(this%nr_connections,
'NROFCONNS', this%memoryPath)
574 end subroutine allocatescalars
578 subroutine allocatearrays(this)
584 call mem_allocate(this%x, this%neq,
'X', this%memoryPath)
585 call mem_allocate(this%rhs, this%neq,
'RHS', this%memoryPath)
586 call mem_allocate(this%active, this%neq,
'IACTIVE', this%memoryPath)
595 end subroutine allocatearrays
599 function getnrofconnections(this)
result(nrConns)
601 integer(I4B) :: nrConns
604 nrconns = this%prim_exchange%nexg
606 end function getnrofconnections
616 call this%matrix%init(sparse, this%memoryPath)
626 character(len=LINELENGTH) :: errmsg
628 conex => this%prim_exchange
629 if (conex%ixt3d > 0)
then
631 if (conex%v_model1%con_ianglex%get() == 0)
then
632 write (errmsg,
'(a,a,a,a,a)')
'XT3D configured on the exchange ', &
633 trim(conex%name),
' but the discretization in model ', &
634 trim(conex%v_model1%name),
' has no ANGLDEGX specified'
637 if (conex%v_model2%con_ianglex%get() == 0)
then
638 write (errmsg,
'(a,a,a,a,a)')
'XT3D configured on the exchange ', &
639 trim(conex%name),
' but the discretization in model ', &
640 trim(conex%v_model2%name),
' has no ANGLDEGX specified'
655 subroutine cfg_dv(this, var_name, subcomp_name, map_type, &
656 sync_stages, exg_var_name)
658 character(len=*) :: var_name
659 character(len=*) :: subcomp_name
660 integer(I4B) :: map_type
661 integer(I4B),
dimension(:) :: sync_stages
662 character(len=*),
optional :: exg_var_name
665 class(*),
pointer :: obj
667 if (.not.
present(exg_var_name)) exg_var_name =
''
670 dist_var%var_name = var_name
671 dist_var%subcomp_name = subcomp_name
672 dist_var%comp_name = this%interface_model%name
673 dist_var%map_type = map_type
674 dist_var%sync_stages = sync_stages
675 dist_var%exg_var_name = exg_var_name
678 call this%iface_dist_vars%Add(obj)
686 class(*),
pointer,
intent(inout) :: obj
690 if (.not.
associated(obj))
return
703 type(
listtype),
intent(inout) :: list
706 class(*),
pointer :: obj
715 type(
listtype),
intent(inout) :: list
716 integer(I4B),
intent(in) :: idx
720 class(*),
pointer :: obj
721 obj => list%GetItem(idx)
This module contains simulation constants.
integer(i4b), parameter linelength
maximum length of a standard line
real(dp), parameter dzero
real constant zero
integer(i4b) function, public getcsrindex(i, j, ia, ja)
Return index for element i,j in CSR storage,.
Refactoring issues towards parallel:
This module defines variable data types.
character(len=lenmempath) function create_mem_path(component, subcomponent, context)
returns the path to the memory object
This module contains simulation methods.
subroutine, public ustop(stopmess, ioutlocal)
Stop the simulation.
subroutine, public store_error(msg, terminate)
Store an error message.
integer(i4b) function, public count_errors()
Return number of errors.
subroutine validateconnection(this)
Validate this connection.
subroutine spatialcon_connect(this)
map interface model connections to our sparse matrix,
class(spatialmodelconnectiontype) function, pointer, public get_smc_from_list(list, idx)
Get the connection from a list.
subroutine spatialcon_df(this)
Define this connection, this is where the discretization (DISU) for the interface model is.
subroutine spatialcon_setmodelptrs(this)
set model pointers to connection
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 t...
subroutine spatialconnection_ctor(this, model, exchange, name)
Construct the spatial connection base.
class(spatialmodelconnectiontype) function, pointer, public cast_as_smc(obj)
Cast to SpatialModelConnectionType.
subroutine, public add_smc_to_list(list, conn)
Add connection to a list.
recursive subroutine addmodelneighbors(this, model_id, virtual_exchanges, depth, is_root, mask)
Add neighbors and nbrs-of-nbrs to the model tree.
subroutine createcoefficientmatrix(this, sparse)
Add connections, handled by the interface model,.
subroutine createmodelhalo(this)
Find all models that might participate in this interface.
subroutine maskownerconnections(this)
Mask the owner's connections.
subroutine spatialcon_ar(this)
Allocate the connection,.
type(listtype), public virtual_exchange_list
class(virtualexchangetype) function, pointer, public get_virtual_exchange_from_list(list, idx)
class(virtualexchangetype) function, pointer, public get_virtual_exchange(exg_id)
Returns a virtual exchange with the specified id.
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...
A generic heterogeneous doubly-linked list.
Class to manage spatial connection of a model to one or more models of the same type....
The Virtual Exchange is based on two Virtual Models and is therefore not always strictly local or rem...