Skip to content

Commit

Permalink
wip
Browse files Browse the repository at this point in the history
  • Loading branch information
wpbonelli committed Mar 3, 2024
1 parent 7906c62 commit ba54b93
Show file tree
Hide file tree
Showing 6 changed files with 395 additions and 361 deletions.
189 changes: 60 additions & 129 deletions src/ExchangeFactory.f90
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@ module ExchangeFactoryModule
use KindModule, only: I4B, LGP
use ConstantsModule, only: LENMEMPATH, LINELENGTH
use SimModule, only: store_error
use SimVariablesModule, only: iout, model_names, model_loc_idx
use CharacterStringModule, only: CharacterStringType
use ArrayHandlersModule, only: ifind
use GwfGwfExchangeModule, only: register_gwfgwf
Expand All @@ -16,158 +15,90 @@ module ExchangeFactoryModule
use VirtualGwtExchangeModule, only: register_virtual_gwtgwt
use VirtualGweExchangeModule, only: register_virtual_gwegwe
use VirtualPrtExchangeModule, only: register_virtual_prtprt
use ExchangeRegistrarModule, only: register_exchange, &
register_actual_exchange, &
register_virtual_exchange

implicit none
private
public :: create_exchanges

contains

subroutine create_exchanges(etypes, efiles, emnames_a, emnames_b, emempaths)
! -- dummy
subroutine create_exchanges(&
exchange_types, &
exchange_filenames, &
exchange_mempaths, &
model1_names, &
model2_names)
! dummy
type(CharacterStringType), dimension(:), contiguous, &
pointer, intent(in) :: etypes !< exg types
pointer, intent(in) :: exchange_types !< exchange types
type(CharacterStringType), dimension(:), contiguous, &
pointer, intent(in) :: efiles !< exg file names
pointer, intent(in) :: exchange_filenames !< exchange input file names
type(CharacterStringType), dimension(:), contiguous, &
pointer, intent(in) :: emnames_a !< model a names
pointer, intent(in) :: exchange_mempaths !< exchange input memory paths
type(CharacterStringType), dimension(:), contiguous, &
pointer, intent(in) :: emnames_b !< model b names
pointer, intent(in) :: model1_names !< model 1 names
type(CharacterStringType), dimension(:), contiguous, &
pointer, intent(in) :: emempaths
! -- local
integer(I4B) :: exg_id, n
integer(I4B) :: m1_id, m2_id
logical(LGP) :: both_remote, both_local
character(len=LINELENGTH) :: fname, name1, name2, exg_name
character(len=LENMEMPATH) :: exg_mempath
character(len=LINELENGTH) :: errmsg, exgtype
! -- formats
character(len=*), parameter :: fmtmerr = "('Error in simulation control ', &
&'file. Could not find model: ', a)"
pointer, intent(in) :: model2_names !< model 2 names
! local
integer(I4B) :: n
integer(I4B) :: id
character(len=LINELENGTH) :: name
character(len=LINELENGTH) :: errmsg
procedure(register_actual_exchange), pointer :: register_actual
procedure(register_virtual_exchange), pointer :: register_virtual

exg_id = 0
do n = 1, size(etypes)
exgtype = etypes(n)
fname = efiles(n)
name1 = emnames_a(n)
name2 = emnames_b(n)
exg_mempath = emempaths(n)
exg_id = exg_id + 1

! find model index in list
m1_id = ifind(model_names, name1)
if (m1_id < 0) then
write (errmsg, fmtmerr) trim(name1)
call store_error(errmsg, terminate=.true.)
end if
m2_id = ifind(model_names, name2)
if (m2_id < 0) then
write (errmsg, fmtmerr) trim(name2)
call store_error(errmsg, terminate=.true.)
end if

! both models on other process? then don't create it here...
both_remote = (model_loc_idx(m1_id) == -1 .and. &
model_loc_idx(m2_id) == -1)
both_local = (model_loc_idx(m1_id) > 0 .and. &
model_loc_idx(m2_id) > 0)
if (.not. both_remote) write (iout, '(4x,a,a,i0,a,i0,a,i0)') &
trim(exgtype), ' exchange ', exg_id, &
' will be created to connect model ', m1_id, &
' with model ', m2_id

select case (exgtype)
id = 0
do n = 1, size(exchange_types)
id = id + 1
select case (etype)
case ('GWF6-GWF6')
write (exg_name, '(a,i0)') 'GWF-GWF_', exg_id
if (.not. both_remote) &
call register_gwfgwf( &
fname, &
exg_name, &
exg_id, &
m1_id, &
m2_id, &
exg_mempath)
call register_virtual_gwfgwf( &
exg_name, &
exg_id, &
m1_id, &
m2_id)
write (name, '(a,i0)') 'GWF-GWF_', id
register_actual => register_gwfgwf
register_virtual => register_virtual_gwfgwf
case ('GWT6-GWT6')
write (exg_name, '(a,i0)') 'GWT-GWT_', exg_id
if (.not. both_remote) &
call register_gwtgwt( &
fname, &
exg_name, &
exg_id, &
m1_id, &
m2_id, &
exg_mempath)
call register_virtual_gwtgwt( &
exg_name, &
exg_id, &
m1_id, &
m2_id)
write (name, '(a,i0)') 'GWT-GWT_', id
register_actual => register_gwtgwt
register_virtual => register_virtual_gwtgwt
case ('GWE6-GWE6')
write (exg_name, '(a,i0)') 'GWE-GWE_', exg_id
if (.not. both_remote) &
call register_gwegwe( &
fname, &
exg_name, &
exg_id, &
m1_id, &
m2_id, &
exg_mempath)
call register_virtual_gwegwe( &
exg_name, &
exg_id, &
m1_id, &
m2_id)
write (name, '(a,i0)') 'GWE-GWE_', id
register_actual => register_gwegwe
register_virtual => register_virtual_gwegwe
case ('GWF6-GWT6')
write (exg_name, '(a,i0)') 'GWF-GWT_', exg_id
if (both_local) &
call register_gwfgwt( &
fname, &
exg_name, &
exg_id, &
m1_id, &
m2_id, &
exg_mempath)
write (name, '(a,i0)') 'GWF-GWT_', id
register_actual => register_gwfgwt
register_virtual => null()
case ('GWF6-GWE6')
write (exg_name, '(a,i0)') 'GWF-GWE_', exg_id
if (both_local) &
call register_gwfgwe( &
fname, &
exg_name, &
exg_id, &
m1_id, &
m2_id, &
exg_mempath)
write (name, '(a,i0)') 'GWF-GWE_', id
register_actual => register_gwfgwe
register_virtual => null()
case ('GWF6-PRT6')
write (exg_name, '(a,i0)') 'GWF-PRT_', exg_id
if (both_local) &
call register_gwfprt( &
fname, &
exg_name, &
exg_id, &
m1_id, &
m2_id, &
exg_mempath)
write (name, '(a,i0)') 'GWF-PRT_', id
register_actual => register_gwfprt
register_virtual => null()
case ('SWF6-GWF6')
write (exg_name, '(a,i0)') 'SWF-GWF_', exg_id
if (both_local) &
call register_swfgwf( &
fname, &
exg_name, &
exg_id, &
m1_id, &
m2_id, &
exg_mempath)
write (name, '(a,i0)') 'SWF-GWF_', id
register_actual => register_swfgwf
register_virtual => null()
case default
write (errmsg, '(a,a)') &
'Unknown simulation exchange type: ', trim(exgtype)
'Unknown simulation exchange type: ', trim(etype)
call store_error(errmsg, terminate=.true.)
end select

! register the exchange
call register_exchange(&
register_actual, &
register_virtual, &
id, &
name, &
exchange_types(n), &
exchange_filenames(n), &
exchange_mempaths(n), &
model1_names(n), &
model2_names(n))
end do
end subroutine create_exchanges

Expand Down
116 changes: 116 additions & 0 deletions src/ExchangeRegistrar.f90
Original file line number Diff line number Diff line change
@@ -0,0 +1,116 @@
module ExchangeRegistrarModule
use KindModule, only: I4B
use ConstantsModule, only: LINELENGTH
use ListsModule, only: basemodellist
use SimVariablesModule, only: iout, model_names, model_loc_idx

implicit none
private
public :: register_exchange
public :: register_actual_exchange
public :: register_virtual_exchange

interface
subroutine register_actual_exchange(id, name, file, model1_id, model2_id, mempath)
import I4B
integer(I4B), intent(in) :: id !< exchange id
character(len=*), intent(in) :: name !< exchange name
character(len=*), intent(in) :: file !< exchange input file
integer(I4B), intent(in) :: model1_id !< index of model 1
integer(I4B), intent(in) :: model2_id !< index of model 2
character(len=*), intent(in) :: mempath !< exchange input memory path
end subroutine
end interface

interface
subroutine register_virtual_exchange(name, id, model1_id, model2_id)
import I4B
character(len=*), intent(in) :: name !< exchange name
integer(I4B), intent(in) :: id !< exchange id
integer(I4B), intent(in) :: model1_id !< index of model 1
integer(I4B), intent(in) :: model2_id !< index of model 2
end subroutine
end interface

contains

subroutine register_exchange(&
register_actual, &
register_virtual, &
exchange_id, &
exchange_name, &
exchange_type, &
exchange_file, &
exchange_mempath, &
model1_name, &
model2_name)
! dummy
procedure(register_actual_exchange), pointer, &
intent(in) :: register_actual
procedure(register_virtual_exchange), pointer, &
intent(in) :: register_virtual
integer(I4B), intent(in) :: exchange_id
character(len=*), intent(in) :: exchange_name
character(len=*), intent(in) :: exchange_type
character(len=*), intent(in) :: exchange_file
character(len=*), intent(in) :: exchange_mempath
character(len=*), intent(in) :: model1_name
character(len=*), intent(in) :: model2_name
! local
logical(LGP) :: both_local
logical(LGP) :: both_remote
logical(LGP) :: same_type
character(len=LINELENGTH) :: errmsg
! formats
character(len=*), parameter :: fmtmerr = "('Error in simulation control ', &
&'file. Could not find model: ', a)"

! find model index in list
m1_id = ifind(model_names, model1_name)
if (m1_id < 0) then
write (errmsg, fmtmerr) trim(model1_name)
call store_error(errmsg, terminate=.true.)
end if
m2_id = ifind(model_names, model2_name)
if (m2_id < 0) then
write (errmsg, fmtmerr) trim(model2_name)
call store_error(errmsg, terminate=.true.)
end if

! both models on other process? then don't create it here...
both_remote = (model_loc_idx(m1_id) == -1 .and. &
model_loc_idx(m2_id) == -1)
both_local = (model_loc_idx(m1_id) > 0 .and. &
model_loc_idx(m2_id) > 0)
if (.not. both_remote) write (iout, '(4x,a,a,i0,a,i0,a,i0)') &
trim(exchange_type), ' exchange ', exchange_id, &
' will be created to connect model ', m1_id, &
' with model ', m2_id

! check if models are of the same type
same_type = exchange_name(1:3) == exchange_name(5:7)

! an actual exchange should be registered if the models
! are the same type and at least one is local, or if the
! models are not the same type and both are local
if ((same_type .and. .not. both_remote) .or. &
(.not. same_type .and. both_local)) &
call register_actual(&
exchange_file, &
exchange_name, &
exchange_id, &
m1_id, &
m2_id, &
exchange_mempath)

! if models are of the same type, register virtual exchange
if (same_type) &
call register_virtual(&
exchange_name, &
exchange_id, &
m1_id, &
m2_id)

end subroutine register_exchange

end module ExchangeRegistrarModule
Loading

0 comments on commit ba54b93

Please sign in to comment.