MODFLOW 6  version 6.7.0.dev3
USGS Modular Hydrologic Model
VirtualGwfExchange.f90
Go to the documentation of this file.
2  use kindmodule, only: i4b, lgp
9  implicit none
10  private
11 
12  public :: add_virtual_gwf_exchange
13 
14  !> For synchronization of GWF specific exchange data:
15  !< the exchange movers.
16  type, public, extends(virtualexchangetype) :: virtualgwfexchangetype
17  type(virtualinttype), pointer :: inmvr => null()
18  type(virtualinttype), pointer :: mvr_maxmvr => null()
19  type(virtualdbl1dtype), pointer :: mvr_qpactual_m1 => null()
20  type(virtualdbl1dtype), pointer :: mvr_qpactual_m2 => null()
21  type(virtualdbl1dtype), pointer :: mvr_qavailable_m1 => null()
22  type(virtualdbl1dtype), pointer :: mvr_qavailable_m2 => null()
23  type(virtualint1dtype), pointer :: mvr_id_mapped_m1 => null()
24  type(virtualint1dtype), pointer :: mvr_id_mapped_m2 => null()
25  ! private
26  logical(LGP), private :: has_mvr !< backing field for function
27  contains
28  procedure :: create => vfx_create
29  procedure :: prepare_stage => vfx_prepare_stage
30  procedure :: destroy => vfx_destroy
31  procedure :: get_send_items => vfx_get_send_items
32  procedure :: get_recv_items => vfx_get_recv_items
33  procedure :: has_mover => vfx_has_mover
34  ! private
35  procedure, private :: allocate_data
36  procedure, private :: deallocate_data
37  procedure, private :: init_virtual_data
38  end type virtualgwfexchangetype
39 
40 contains
41 
42 !> @brief Add a virtual GWF-GWF exchange to the simulation
43 !<
44  subroutine add_virtual_gwf_exchange(name, exchange_id, model1_id, model2_id)
45  integer(I4B) :: exchange_id
46  character(len=*) :: name
47  integer(I4B) :: model1_id
48  integer(I4B) :: model2_id
49  ! local
50  class(virtualgwfexchangetype), pointer :: v_exg
51  class(*), pointer :: obj_ptr
52 
53  allocate (v_exg)
54  call v_exg%create(name, exchange_id, model1_id, model2_id)
55 
56  obj_ptr => v_exg
57  call virtual_exchange_list%Add(obj_ptr)
58 
59  end subroutine add_virtual_gwf_exchange
60 
61 !> @brief Create a virtual GWF-GWF exchange
62 !<
63  subroutine vfx_create(this, name, exg_id, m1_id, m2_id)
64  class(virtualgwfexchangetype) :: this
65  character(len=*) :: name
66  integer(I4B) :: exg_id
67  integer(I4B) :: m1_id
68  integer(I4B) :: m2_id
69 
70  call this%VirtualExchangeType%create(name, exg_id, m1_id, m2_id)
71  this%container_type = vdc_gwfexg_type
72 
73  call this%allocate_data()
74  call this%init_virtual_data()
75 
76  this%has_mvr = .false.
77 
78  end subroutine vfx_create
79 
80  subroutine init_virtual_data(this)
81  class(virtualgwfexchangetype) :: this
82  ! local
83  logical(LGP) :: is_nodem1_local
84  logical(LGP) :: is_nodem2_local
85 
86  is_nodem1_local = this%v_model1%is_local
87  is_nodem2_local = this%v_model2%is_local
88  call this%set(this%inmvr%base(), 'INMVR', '', map_all_type)
89  call this%set(this%mvr_maxmvr%base(), 'MAXMVR', 'MVR', map_all_type)
90  ! these follow locality of nodem1,2
91  call this%set(this%mvr_qpactual_m1%base(), 'QPACTUAL_M1', 'MVR', &
92  map_all_type, is_nodem1_local)
93  call this%set(this%mvr_qpactual_m2%base(), 'QPACTUAL_M2', 'MVR', &
94  map_all_type, is_nodem2_local)
95  call this%set(this%mvr_qavailable_m1%base(), 'QAVAILABLE_M1', 'MVR', &
96  map_all_type, is_nodem1_local)
97  call this%set(this%mvr_qavailable_m2%base(), 'QAVAILABLE_M2', 'MVR', &
98  map_all_type, is_nodem2_local)
99  call this%set(this%mvr_id_mapped_m1%base(), 'ID_MAPPED_M1', 'MVR', &
100  map_all_type, is_nodem1_local)
101  call this%set(this%mvr_id_mapped_m2%base(), 'ID_MAPPED_M2', 'MVR', &
102  map_all_type, is_nodem2_local)
103 
104  end subroutine init_virtual_data
105 
106  subroutine vfx_prepare_stage(this, stage)
107  class(virtualgwfexchangetype) :: this
108  integer(I4B) :: stage
109  ! local
110  integer(I4B) :: nmax
111 
112  ! prepare base exchange data items
113  call this%VirtualExchangeType%prepare_stage(stage)
114 
115  if (stage == stg_aft_exg_df) then
116 
117  ! always synchronize mover flag
118  call this%map(this%inmvr%base(), (/stg_aft_exg_df/))
119 
120  else if (stage == stg_aft_con_cr) then
121 
122  ! at this point we know:
123  if (this%inmvr%get() > 0) then
124  this%has_mvr = .true.
125  end if
126 
127  else if (stage == stg_bfr_con_ar) then
128 
129  ! only when MVR is locally active (i.e. primary exchange)
130  if (this%has_mvr .and. this%is_local) then
131  call this%map(this%mvr_maxmvr%base(), (/stg_bfr_con_ar/))
132  end if
133 
134  else if (stage == stg_aft_con_ar) then
135 
136  ! only when MVR is locally active
137  nmax = 0
138  if (this%has_mvr .and. this%is_local) nmax = this%mvr_maxmvr%get()
139 
140  if (nmax > 0) then
141  call this%map(this%mvr_qpactual_m1%base(), nmax, (/stg_bfr_exg_fc/))
142  call this%map(this%mvr_qpactual_m2%base(), nmax, (/stg_bfr_exg_fc/))
143  call this%map(this%mvr_qavailable_m1%base(), nmax, (/stg_bfr_exg_fc/))
144  call this%map(this%mvr_qavailable_m2%base(), nmax, (/stg_bfr_exg_fc/))
145  call this%map(this%mvr_id_mapped_m1%base(), nmax, (/stg_aft_con_rp/))
146  call this%map(this%mvr_id_mapped_m2%base(), nmax, (/stg_aft_con_rp/))
147  else
148  call this%map(this%mvr_qpactual_m1%base(), 0, (/stg_never/))
149  call this%map(this%mvr_qpactual_m2%base(), 0, (/stg_never/))
150  call this%map(this%mvr_qavailable_m1%base(), 0, (/stg_never/))
151  call this%map(this%mvr_qavailable_m2%base(), 0, (/stg_never/))
152  call this%map(this%mvr_id_mapped_m1%base(), 0, (/stg_never/))
153  call this%map(this%mvr_id_mapped_m2%base(), 0, (/stg_never/))
154  end if
155 
156  end if
157 
158  end subroutine vfx_prepare_stage
159 
160  subroutine vfx_get_recv_items(this, stg, rank, vi)
161  class(virtualgwfexchangetype) :: this
162  integer(I4B) :: stg !< stage
163  integer(I4B) :: rank !< rank of remote process
164  type(stlvecint) :: vi !< virtual data items
165 
166  ! get base items to receive
167  call this%VirtualExchangeType%get_recv_items(stg, rank, vi)
168 
169  ! add more MVR items that follow nodem1/nodem2 pattern,
170  ! see comments in VirtualExchange for more details
171  if (this%is_local .and. rank == this%orig_rank) then
172  if (this%mvr_id_mapped_m1%is_remote) then
173  ! only receive for model1
174  call this%add_vdi_for_stage(this%mvr_qpactual_m1%base(), stg, vi)
175  call this%add_vdi_for_stage(this%mvr_qavailable_m1%base(), stg, vi)
176  call this%add_vdi_for_stage(this%mvr_id_mapped_m1%base(), stg, vi)
177  end if
178  if (this%mvr_id_mapped_m2%is_remote) then
179  ! only receive for model2
180  call this%add_vdi_for_stage(this%mvr_qpactual_m2%base(), stg, vi)
181  call this%add_vdi_for_stage(this%mvr_qavailable_m2%base(), stg, vi)
182  call this%add_vdi_for_stage(this%mvr_id_mapped_m2%base(), stg, vi)
183  end if
184  end if
185 
186  end subroutine vfx_get_recv_items
187 
188  subroutine vfx_get_send_items(this, stg, rank, vi)
189  class(virtualgwfexchangetype) :: this
190  integer(I4B) :: stg !< stage
191  integer(I4B) :: rank !< rank of remote process
192  type(stlvecint) :: vi !< virtual data items
193 
194  ! get base items to send
195  call this%VirtualExchangeType%get_send_items(stg, rank, vi)
196 
197  ! add more MVR items that follow nodem1/nodem2 pattern,
198  ! see comments in VirtualExchange for more details
199  if (this%is_local .and. rank == this%orig_rank) then
200  if (.not. this%mvr_id_mapped_m1%is_remote) then
201  ! only receive for model1
202  call this%add_vdi_for_stage(this%mvr_qpactual_m1%base(), stg, vi)
203  call this%add_vdi_for_stage(this%mvr_qavailable_m1%base(), stg, vi)
204  call this%add_vdi_for_stage(this%mvr_id_mapped_m1%base(), stg, vi)
205  end if
206  if (.not. this%mvr_id_mapped_m2%is_remote) then
207  ! only receive for model2
208  call this%add_vdi_for_stage(this%mvr_qpactual_m2%base(), stg, vi)
209  call this%add_vdi_for_stage(this%mvr_qavailable_m2%base(), stg, vi)
210  call this%add_vdi_for_stage(this%mvr_id_mapped_m2%base(), stg, vi)
211  end if
212  end if
213 
214  end subroutine vfx_get_send_items
215 
216  !> @brief Override
217  !<
218  function vfx_has_mover(this) result(has_mover)
219  class(virtualgwfexchangetype) :: this
220  logical(LGP) :: has_mover
221 
222  has_mover = this%has_mvr
223 
224  end function vfx_has_mover
225 
226  subroutine allocate_data(this)
227  class(virtualgwfexchangetype) :: this
228 
229  allocate (this%inmvr)
230  allocate (this%mvr_maxmvr)
231  allocate (this%mvr_qpactual_m1)
232  allocate (this%mvr_qpactual_m2)
233  allocate (this%mvr_qavailable_m1)
234  allocate (this%mvr_qavailable_m2)
235  allocate (this%mvr_id_mapped_m1)
236  allocate (this%mvr_id_mapped_m2)
237 
238  end subroutine allocate_data
239 
240  subroutine deallocate_data(this)
241  class(virtualgwfexchangetype) :: this
242 
243  deallocate (this%inmvr)
244  deallocate (this%mvr_maxmvr)
245  deallocate (this%mvr_qpactual_m1)
246  deallocate (this%mvr_qpactual_m2)
247  deallocate (this%mvr_qavailable_m1)
248  deallocate (this%mvr_qavailable_m2)
249  deallocate (this%mvr_id_mapped_m1)
250  deallocate (this%mvr_id_mapped_m2)
251 
252  end subroutine deallocate_data
253 
254  subroutine vfx_destroy(this)
255  class(virtualgwfexchangetype) :: this
256 
257  call this%VirtualExchangeType%destroy()
258  call this%deallocate_data()
259 
260  end subroutine vfx_destroy
261 
262 end module virtualgwfexchangemodule
This module defines variable data types.
Definition: kind.f90:8
integer(i4b), parameter, public stg_aft_con_ar
afterr connection allocate read
Definition: SimStages.f90:18
integer(i4b), parameter, public stg_aft_exg_df
after exchange define
Definition: SimStages.f90:12
integer(i4b), parameter, public stg_never
never
Definition: SimStages.f90:9
integer(i4b), parameter, public stg_aft_con_cr
after connection create
Definition: SimStages.f90:13
integer(i4b), parameter, public stg_bfr_exg_fc
before exchange formulate (per solution)
Definition: SimStages.f90:23
integer(i4b), parameter, public stg_bfr_con_ar
before connection allocate read
Definition: SimStages.f90:17
integer(i4b), parameter, public stg_aft_con_rp
after connection read prepare
Definition: SimStages.f90:20
subroutine destroy(this)
Definition: STLVecInt.f90:183
integer(i4b), parameter, public map_all_type
Definition: VirtualBase.f90:13
integer(i4b), parameter, public vdc_gwfexg_type
type(listtype), public virtual_exchange_list
subroutine deallocate_data(this)
subroutine init_virtual_data(this)
subroutine allocate_data(this)
subroutine, public add_virtual_gwf_exchange(name, exchange_id, model1_id, model2_id)
Add a virtual GWF-GWF exchange to the simulation.
logical(lgp) function vfx_has_mover(this)
Override.
subroutine vfx_create(this, name, exg_id, m1_id, m2_id)
Create a virtual GWF-GWF exchange.
subroutine vfx_prepare_stage(this, stage)
subroutine vfx_get_send_items(this, stg, rank, vi)
subroutine vfx_get_recv_items(this, stg, rank, vi)
The Virtual Exchange is based on two Virtual Models and is therefore not always strictly local or rem...
For synchronization of GWF specific exchange data: