MODFLOW 6  version 6.8.0.dev0
USGS Modular Hydrologic Model
GwfExchangeMover.f90
Go to the documentation of this file.
2  use kindmodule, only: i4b, dp, lgp
7  use basedismodule
8  use gwfmvrmodule
10  implicit none
11  private
12 
13  public :: exg_mvr_cr
14 
15  !> @brief Extends model mover for exchanges to also handle the
16  !< parallel case where the models are not on the same process.
17  type, public, extends(gwfmvrtype) :: gwfexgmovertype
18  class(virtualmodeltype), pointer :: model1 => null() !< virtual model 1
19  class(virtualmodeltype), pointer :: model2 => null() !< virtual model 2
20  logical(LGP), dimension(:), pointer, contiguous :: prov_is_m1 => null() !< .true. when the providing package is part of model 1
21  real(dp), dimension(:), pointer, contiguous :: qpactual_m1 => null() !< stores qpactual for synchronization when provider is in model 1
22  real(dp), dimension(:), pointer, contiguous :: qpactual_m2 => null() !< stores qpactual for synchronization when provider is in model 2
23  real(dp), dimension(:), pointer, contiguous :: qavailable_m1 => null() !< stores qavailable for synchronization when provider is in model 1
24  real(dp), dimension(:), pointer, contiguous :: qavailable_m2 => null() !< stores qavailable for synchronization when provider is in model 2
25  integer(I4B), dimension(:), pointer, contiguous :: id_mapped_m1 => null() !< stores the mapped feature ids for synchronization when provider is in model 1
26  integer(I4B), dimension(:), pointer, contiguous :: id_mapped_m2 => null() !< stores the mapped feature ids for synchronization when provider is in model 2
27  contains
28  procedure :: mvr_da => xmvr_da
29  procedure :: xmvr_cf
30  procedure :: mvr_fc => xmvr_fc
31  procedure :: mvr_bd => xmvr_bd
36  end type
37 
38 contains
39 
40  subroutine exg_mvr_cr(exg_mvr, name_parent, inunit, iout, dis)
41  class(gwfexgmovertype), pointer :: exg_mvr
42  character(len=*), intent(in) :: name_parent
43  integer(I4B), intent(in) :: inunit
44  integer(I4B), intent(in) :: iout
45  class(disbasetype), pointer :: dis
46 
47  allocate (exg_mvr)
48 
49  ! Init through base
50  call exg_mvr%mvr_init(name_parent, inunit, iout, dis, 1)
51 
52  end subroutine exg_mvr_cr
53 
54  subroutine xmvr_check_packages(this)
55  use constantsmodule, only: linelength
58  class(gwfexgmovertype), intent(inout) :: this
59  ! local
60  character(len=LENMODELNAME) :: mname
61  character(len=LENPACKAGENAME) :: pname
62  class(virtualmodeltype), pointer :: vm
63  character(len=LINELENGTH) :: errmsg
64  integer(I4B) :: i
65  integer(I4B), pointer :: imover_ptr
66 
67  do i = 1, size(this%pckMemPaths)
68  ! check only when local
69  call split_mem_path(this%pckMemPaths(i), mname, pname)
70  vm => get_virtual_model(mname)
71  if (vm%is_local) then
72  ! check if PackageMover is active in package:
73  imover_ptr => null()
74  call mem_setptr(imover_ptr, 'IMOVER', trim(this%pckMemPaths(i)))
75  if (imover_ptr == 0) then
76  write (errmsg, '(a, a, a)') &
77  'ERROR. MODEL AND PACKAGE "', &
78  trim(this%pckMemPaths(i)), &
79  '" DOES NOT HAVE MOVER SPECIFIED IN OPTIONS BLOCK.'
80  call store_error(errmsg)
81  end if
82  end if
83  !
84  ! ensure that the current model name, which is listed in the PACKAGES
85  ! block of the exchange MVR input, is one of the two models connected
86  ! by the exchange. If not, then the model should not be listed.
87  if (mname == this%model1%name .or. mname == this%model2%name) then
88  continue
89  else
90  write (errmsg, '(a, a, a)') 'The input for an exchange mover &
91  &lists a model name ("', trim(mname), '") in the PACKAGES &
92  &input block that is not a member of the exchange.'
93  call store_error(errmsg)
94  end if
95  end do
96 
97  if (count_errors() > 0) then
98  call this%parser%StoreErrorUnit()
99  end if
100 
101  end subroutine xmvr_check_packages
102 
103  !> @brief Overrides GWF MVR routine to skip assigning
104  !< pointers when the package is not local
105  subroutine xmvr_assign_packagemovers(this)
106  class(gwfexgmovertype), intent(inout) :: this !< this exchange mover
107  ! local
108  integer(I4B) :: i
109  character(len=LENMODELNAME) :: mname
110  character(len=LENPACKAGENAME) :: pname
111  class(virtualmodeltype), pointer :: vm
112 
113  do i = 1, size(this%pckMemPaths)
114  if (this%pakmovers(i)%memoryPath == '') then
115  ! is it local?
116  call split_mem_path(this%pckMemPaths(i), mname, pname)
117  vm => get_virtual_model(mname)
118  if (vm%is_local) then
119  ! yes, we need the pointers
120  call set_packagemover_pointer(this%pakmovers(i), &
121  trim(this%pckMemPaths(i)))
122  end if
123  end if
124  end do
125  end subroutine xmvr_assign_packagemovers
126 
127  !> @brief Overrides mover initialization in GWF MVR to
128  !! deactivate remote parts and build up sync. arrays
129  !< for mapped feature ids
130  subroutine xmvr_initialize_movers(this, nr_active_movers)
131  class(gwfexgmovertype) :: this
132  integer(I4B) :: nr_active_movers
133  ! local
134  integer(I4B) :: i
135  character(len=LENMODELNAME) :: mname
136  character(len=LENPACKAGENAME) :: pname
137  class(virtualmodeltype), pointer :: vm
138  class(packagemovertype), allocatable :: pkg_mvr
139 
140  call this%GwfMvrType%initialize_movers(nr_active_movers)
141 
142  this%prov_is_m1 = .false.
143 
144  ! deactivate remote parts
145  do i = 1, nr_active_movers
146  call split_mem_path(this%mvr(i)%mem_path_src, mname, pname)
147  vm => get_virtual_model(mname)
148  this%mvr(i)%is_provider_active = vm%is_local
149  this%prov_is_m1(i) = associated(vm, this%model1)
150  call split_mem_path(this%mvr(i)%mem_path_tgt, mname, pname)
151  vm => get_virtual_model(mname)
152  this%mvr(i)%is_receiver_active = vm%is_local
153  end do
154 
155  ! loop over mvr's, if provider is active,
156  ! store mapped feature index in array for sync
157  allocate (pkg_mvr)
158 
159  do i = 1, nr_active_movers
160  if (this%mvr(i)%is_provider_active) then
161  ! store mapped feature id in array (for synchronization when parallel)
162  call set_packagemover_pointer(pkg_mvr, this%mvr(i)%mem_path_src)
163  if (this%prov_is_m1(i)) then
164  this%id_mapped_m1(i) = pkg_mvr%iprmap(this%mvr(i)%iRchNrSrc)
165  this%id_mapped_m2(i) = -1
166  else
167  this%id_mapped_m1(i) = -1
168  this%id_mapped_m2(i) = pkg_mvr%iprmap(this%mvr(i)%iRchNrSrc)
169  end if
170  end if
171  end do
172 
173  end subroutine xmvr_initialize_movers
174 
175  !> @brief Calculates qpactual and stores it for synchronization
176  !<
177  subroutine xmvr_cf(this)
178  class(gwfexgmovertype) :: this
179  ! local
180  integer(I4B) :: i
181 
182  do i = 1, this%nmvr
183  if (this%mvr(i)%is_provider_active) then
184 
185  call this%mvr(i)%update_provider()
186 
187  ! copy calculated rate to arrays for synchronization:
188  if (this%prov_is_m1(i)) then
189  this%qpactual_m1(i) = this%mvr(i)%qpactual
190  this%qavailable_m1(i) = this%mvr(i)%qavailable
191  this%qpactual_m2(i) = dnodata
192  this%qavailable_m2(i) = dnodata
193  else
194  this%qpactual_m1(i) = dnodata
195  this%qavailable_m1(i) = dnodata
196  this%qpactual_m2(i) = this%mvr(i)%qpactual
197  this%qavailable_m2(i) = this%mvr(i)%qavailable
198  end if
199  end if
200  end do
201 
202  end subroutine xmvr_cf
203 
204  !> @brief Assign synced qpactual to mover and update receiver
205  !<
206  subroutine xmvr_fc(this)
207  class(gwfexgmovertype) :: this
208  ! local
209  integer(I4B) :: i
210 
211  do i = 1, this%nmvr
212  if (this%mvr(i)%is_receiver_active) then
213  ! copy from synchronization arrays back into movers:
214  if (this%prov_is_m1(i)) then
215  this%mvr(i)%qpactual = this%qpactual_m1(i)
216  this%mvr(i)%qavailable = this%qavailable_m1(i)
217  else
218  this%mvr(i)%qpactual = this%qpactual_m2(i)
219  this%mvr(i)%qavailable = this%qavailable_m2(i)
220  end if
221  call this%mvr(i)%update_receiver()
222  end if
223  end do
224 
225  end subroutine xmvr_fc
226 
227  !> @brief Overrides budget routine to first assign the
228  !< mapped features ids from the synchronization arrays
229  subroutine xmvr_bd(this)
230  class(gwfexgmovertype) :: this
231  ! local
232  integer(I4B) :: i
233 
234  ! copy from synchronization arrays back into movers:
235  do i = 1, this%nmvr
236  if (this%prov_is_m1(i)) then
237  this%mvr(i)%iRchNrSrcMapped = this%id_mapped_m1(i)
238  else
239  this%mvr(i)%iRchNrSrcMapped = this%id_mapped_m2(i)
240  end if
241  end do
242 
243  call this%fill_budobj()
244 
245  end subroutine xmvr_bd
246 
247  subroutine xmvr_allocate_arrays(this)
248  class(gwfexgmovertype) :: this
249  ! local
250  integer(I4B) :: i
251 
252  call this%GwfMvrType%allocate_arrays()
253 
254  allocate (this%prov_is_m1(this%maxmvr))
255  call mem_allocate(this%qpactual_m1, this%maxmvr, 'QPACTUAL_M1', &
256  this%memoryPath)
257  call mem_allocate(this%qpactual_m2, this%maxmvr, 'QPACTUAL_M2', &
258  this%memoryPath)
259  call mem_allocate(this%qavailable_m1, this%maxmvr, 'QAVAILABLE_M1', &
260  this%memoryPath)
261  call mem_allocate(this%qavailable_m2, this%maxmvr, 'QAVAILABLE_M2', &
262  this%memoryPath)
263  call mem_allocate(this%id_mapped_m1, this%maxmvr, 'ID_MAPPED_M1', &
264  this%memoryPath)
265  call mem_allocate(this%id_mapped_m2, this%maxmvr, 'ID_MAPPED_M2', &
266  this%memoryPath)
267 
268  do i = 1, this%maxmvr
269  this%id_mapped_m1(i) = 0
270  this%id_mapped_m2(i) = 0
271  this%qpactual_m1(i) = dnodata
272  this%qpactual_m2(i) = dnodata
273  this%qavailable_m1(i) = dnodata
274  this%qavailable_m2(i) = dnodata
275  end do
276 
277  end subroutine xmvr_allocate_arrays
278 
279  subroutine xmvr_da(this)
280  class(gwfexgmovertype) :: this
281 
282  call this%GwfMvrType%mvr_da()
283 
284  deallocate (this%prov_is_m1)
285  call mem_deallocate(this%qpactual_m1)
286  call mem_deallocate(this%qpactual_m2)
287  call mem_deallocate(this%qavailable_m1)
288  call mem_deallocate(this%qavailable_m2)
289  call mem_deallocate(this%id_mapped_m1)
290  call mem_deallocate(this%id_mapped_m2)
291 
292  end subroutine xmvr_da
293 
294 end module gwfexgmovermodule
This module contains simulation constants.
Definition: Constants.f90:9
integer(i4b), parameter linelength
maximum length of a standard line
Definition: Constants.f90:45
integer(i4b), parameter lenmodelname
maximum length of the model name
Definition: Constants.f90:22
integer(i4b), parameter lenpackagename
maximum length of the package name
Definition: Constants.f90:23
real(dp), parameter dnodata
real no data constant
Definition: Constants.f90:95
real(dp), parameter dzero
real constant zero
Definition: Constants.f90:65
subroutine xmvr_initialize_movers(this, nr_active_movers)
Overrides mover initialization in GWF MVR to deactivate remote parts and build up sync....
subroutine xmvr_da(this)
subroutine xmvr_assign_packagemovers(this)
Overrides GWF MVR routine to skip assigning.
subroutine xmvr_check_packages(this)
subroutine xmvr_fc(this)
Assign synced qpactual to mover and update receiver.
subroutine xmvr_cf(this)
Calculates qpactual and stores it for synchronization.
subroutine xmvr_bd(this)
Overrides budget routine to first assign the.
subroutine, public exg_mvr_cr(exg_mvr, name_parent, inunit, iout, dis)
subroutine xmvr_allocate_arrays(this)
subroutine mvr_da(this)
Deallocate.
Definition: gwf-mvr.f90:633
subroutine initialize_movers(this, nr_active_movers)
Definition: gwf-mvr.f90:405
subroutine check_packages(this)
Check to make sure packages have mover activated.
Definition: gwf-mvr.f90:936
subroutine mvr_bd(this)
Fill the mover budget object.
Definition: gwf-mvr.f90:478
subroutine assign_packagemovers(this)
Assign pointer to each package's packagemover object.
Definition: gwf-mvr.f90:969
subroutine mvr_fc(this)
Calculate qfrommvr as a function of qtomvr.
Definition: gwf-mvr.f90:437
subroutine allocate_arrays(this)
Allocate package arrays.
Definition: gwf-mvr.f90:1026
This module defines variable data types.
Definition: kind.f90:8
subroutine split_mem_path(mem_path, component, subcomponent)
Split the memory path into component(s)
subroutine, public set_packagemover_pointer(packagemover, memPath)
This module contains simulation methods.
Definition: Sim.f90:10
subroutine, public store_error(msg, terminate)
Store an error message.
Definition: Sim.f90:92
integer(i4b) function, public count_errors()
Return number of errors.
Definition: Sim.f90:59
subroutine, public store_error_unit(iunit, terminate)
Store the file unit number.
Definition: Sim.f90:168
Extends model mover for exchanges to also handle the.