MODFLOW 6  version 6.6.0.dev0
USGS Modular Hydrologic Model
VirtualBase.f90
Go to the documentation of this file.
2  use kindmodule, only: i4b, dp, lgp
3  use listmodule
8  implicit none
9  private
10 
12 
13  integer(I4B), public, parameter :: map_all_type = 0
14  integer(I4B), public, parameter :: map_node_type = 1
15  integer(I4B), public, parameter :: map_conn_type = 2
16  integer(I4B), public, parameter :: nr_vdc_element_maps = 2
17 
18  !> This is a generic data structure to virtualize pieces
19  !! of memory in 2 distinct ways:
20  !!
21  !! 1) Virtualize remote memory
22  !! This concerns memory residing on another process.
23  !! Typically, these pieces are subsets of certain model
24  !! and exchange data and lookup tables are kept with the
25  !! data to manage their mapping. The stage(s) at which
26  !! to synchronize the virtual memory is stored as well.
27  !!
28  !! 2) Virtualize local memory
29  !! In this case no virtual memory item is created, no
30  !! lookup tables and synchronization are necessary.
31  !! The virtual memory item will be pointed to the
32  !! original memory location at the requested
33  !! synchronization stage.
34  !<
35  type, abstract, public :: virtualdatatype
36  logical(LGP) :: is_remote = .false. !< is remote memory, when true (default is false)
37  character(len=LENVARNAME) :: var_name !< variable name
38  character(len=LENCOMPONENTNAME) :: subcmp_name !< subcomponent name, e.g. package name
39  character(len=LENMEMPATH) :: mem_path !< memory path
40  integer(I4B), dimension(:), allocatable :: sync_stages !< stage(s) at which to synchronize
41  integer(I4B) :: map_type !< the type of map
42  logical(LGP) :: is_reduced !< when true, the discontinuous remote data is compressed
43  !! into contiguous virtual memory
44  integer(I4B), dimension(:), &
45  pointer, contiguous :: remote_elem_shift => null() !< contiguous list with 0-based remote indexes
46  !! (this is important for creating mpi data types)
47  integer(I4B), dimension(:), &
48  pointer, contiguous :: remote_to_virtual => null() !< sparse list which maps remote index to virtual
49  type(memorytype), pointer :: virtual_mt => null()
50  contains
51  procedure(vm_allocate_if), deferred :: vm_allocate
52  procedure(vm_deallocate_if), deferred :: vm_deallocate
53  procedure :: base => vm_to_base
54  procedure :: check_stage => vm_check_stage
55  procedure :: link => vm_link
56  procedure :: get_element_map
57  end type
58 
59  type, public, extends(virtualdatatype) :: virtualinttype
60  integer(I4B), private, pointer :: intsclr
61  contains
62  procedure :: vm_allocate => vm_allocate_int
63  procedure :: vm_deallocate => vm_deallocate_int
64  procedure :: get => get_int
65  end type
66 
67  type, public, extends(virtualdatatype) :: virtualint1dtype
68  integer(I4B), dimension(:), pointer, contiguous :: int1d
69  contains
70  procedure :: vm_allocate => vm_allocate_int1d
71  procedure :: vm_deallocate => vm_deallocate_int1d
72  procedure :: get => get_int1d
73  procedure :: get_array => get_array_int1d
74  end type
75 
76  type, public, extends(virtualdatatype) :: virtualdbltype
77  real(dp), private, pointer :: dblsclr
78  contains
79  procedure :: vm_allocate => vm_allocate_dbl
80  procedure :: vm_deallocate => vm_deallocate_dbl
81  procedure :: get => get_dbl
82  end type
83 
84  type, public, extends(virtualdatatype) :: virtualdbl1dtype
85  real(dp), dimension(:), pointer, contiguous :: dbl1d
86  contains
87  procedure :: vm_allocate => vm_allocate_dbl1d
88  procedure :: vm_deallocate => vm_deallocate_dbl1d
89  procedure :: get => get_dbl1d
90  procedure :: get_array => get_array_dbl1d
91  end type
92 
93  type, public, extends(virtualdatatype) :: virtualdbl2dtype
94  real(dp), dimension(:, :), pointer, contiguous :: dbl2d
95  contains
96  procedure :: vm_allocate => vm_allocate_dbl2d
97  procedure :: vm_deallocate => vm_deallocate_dbl2d
98  procedure :: get => get_dbl2d
99  procedure :: get_array => get_array_dbl2d
100  end type
101 
102  ! etc...
103  abstract interface
104  subroutine vm_allocate_if(this, var_name, mem_path, shape)
105  import virtualdatatype, i4b
106  class(virtualdatatype) :: this
107  character(len=*) :: var_name
108  character(len=*) :: mem_path
109  integer(I4B), dimension(:) :: shape
110  end subroutine vm_allocate_if
111  subroutine vm_deallocate_if(this)
112  import virtualdatatype
113  class(virtualdatatype) :: this
114  end subroutine vm_deallocate_if
115  end interface
116 
117 contains
118 
119  function vm_to_base(this) result(base_ptr)
120  class(virtualdatatype), target :: this
121  class(virtualdatatype), pointer :: base_ptr
122 
123  base_ptr => this
124 
125  end function vm_to_base
126 
127  !> @brief Check if this data item requires syncing
128  !< for this particular stage
129  function vm_check_stage(this, stage) result(has_stage)
130  use arrayhandlersmodule, only: ifind
131  class(virtualdatatype), target :: this
132  integer(I4B) :: stage, stg_idx
133  logical(LGP) :: has_stage
134 
135  has_stage = .false.
136  if (allocated(this%sync_stages)) then
137  stg_idx = ifind(this%sync_stages, stage)
138  has_stage = (stg_idx > 0)
139  end if
140 
141  end function vm_check_stage
142 
143  subroutine vm_link(this)
144  class(virtualdatatype), target :: this
145  ! local
146  logical(LGP) :: found
147 
148  call get_from_memorystore(this%var_name, this%mem_path, &
149  this%virtual_mt, found)
150 
151  end subroutine vm_link
152 
153  !> @brief Return array with offsets for elements
154  !< mapped in this virtual data item
155  function get_element_map(this) result(el_map)
156  class(virtualdatatype), target :: this
157  integer(I4B), dimension(:), pointer, contiguous :: el_map
158 
159  el_map => null()
160  if (this%map_type > 0) then
161  el_map => this%remote_elem_shift
162  end if
163 
164  end function get_element_map
165 
166  subroutine vm_allocate_int(this, var_name, mem_path, shape)
167  class(virtualinttype) :: this
168  character(len=*) :: var_name
169  character(len=*) :: mem_path
170  integer(I4B), dimension(:) :: shape
171 
172  call mem_allocate(this%intsclr, var_name, mem_path)
173 
174  end subroutine vm_allocate_int
175 
176  subroutine vm_deallocate_int(this)
177  class(virtualinttype) :: this
178 
179  if (this%is_remote) call mem_deallocate(this%intsclr)
180 
181  end subroutine vm_deallocate_int
182 
183  subroutine vm_allocate_int1d(this, var_name, mem_path, shape)
184  class(virtualint1dtype) :: this
185  character(len=*) :: var_name
186  character(len=*) :: mem_path
187  integer(I4B), dimension(:) :: shape
188 
189  call mem_allocate(this%int1d, shape(1), var_name, mem_path)
190 
191  end subroutine vm_allocate_int1d
192 
193  subroutine vm_deallocate_int1d(this)
194  class(virtualint1dtype) :: this
195 
196  if (this%is_remote) call mem_deallocate(this%int1d)
197 
198  end subroutine vm_deallocate_int1d
199 
200  subroutine vm_allocate_dbl(this, var_name, mem_path, shape)
201  class(virtualdbltype) :: this
202  character(len=*) :: var_name
203  character(len=*) :: mem_path
204  integer(I4B), dimension(:) :: shape
205 
206  call mem_allocate(this%dblsclr, var_name, mem_path)
207 
208  end subroutine vm_allocate_dbl
209 
210  subroutine vm_deallocate_dbl(this)
211  class(virtualdbltype) :: this
212 
213  if (this%is_remote) call mem_deallocate(this%dblsclr)
214 
215  end subroutine vm_deallocate_dbl
216 
217  subroutine vm_allocate_dbl1d(this, var_name, mem_path, shape)
218  class(virtualdbl1dtype) :: this
219  character(len=*) :: var_name
220  character(len=*) :: mem_path
221  integer(I4B), dimension(:) :: shape
222 
223  call mem_allocate(this%dbl1d, shape(1), var_name, mem_path)
224 
225  end subroutine vm_allocate_dbl1d
226 
227  subroutine vm_deallocate_dbl1d(this)
228  class(virtualdbl1dtype) :: this
229 
230  if (this%is_remote) call mem_deallocate(this%dbl1d)
231 
232  end subroutine vm_deallocate_dbl1d
233 
234  subroutine vm_allocate_dbl2d(this, var_name, mem_path, shape)
235  class(virtualdbl2dtype) :: this
236  character(len=*) :: var_name
237  character(len=*) :: mem_path
238  integer(I4B), dimension(:) :: shape
239 
240  call mem_allocate(this%dbl2d, shape(1), shape(2), var_name, mem_path)
241 
242  end subroutine vm_allocate_dbl2d
243 
244  subroutine vm_deallocate_dbl2d(this)
245  class(virtualdbl2dtype) :: this
246 
247  if (this%is_remote) call mem_deallocate(this%dbl2d)
248 
249  end subroutine vm_deallocate_dbl2d
250 
251  function get_int(this) result(val)
252  class(virtualinttype) :: this
253  integer(I4B) :: val
254 
255  val = this%virtual_mt%intsclr
256 
257  end function get_int
258 
259  function get_int1d(this, i_rmt) result(val)
260  class(virtualint1dtype) :: this
261  integer(I4B) :: i_rmt
262  integer(I4B) :: val
263  ! local
264  integer(I4B) :: i_vrt
265 
266  if (this%is_reduced) then
267  i_vrt = this%remote_to_virtual(i_rmt)
268  else
269  i_vrt = i_rmt
270  end if
271  val = this%virtual_mt%aint1d(i_vrt)
272 
273  end function get_int1d
274 
275  function get_array_int1d(this) result(array)
276  class(virtualint1dtype) :: this
277  integer(I4B), dimension(:), pointer, contiguous :: array
278 
279  array => this%virtual_mt%aint1d
280 
281  end function get_array_int1d
282 
283  function get_dbl(this) result(val)
284  class(virtualdbltype) :: this
285  real(dp) :: val
286 
287  val = this%virtual_mt%dblsclr
288 
289  end function get_dbl
290 
291  function get_dbl1d(this, i_rmt) result(val)
292  class(virtualdbl1dtype) :: this
293  integer(I4B) :: i_rmt
294  real(dp) :: val
295  ! local
296  integer(I4B) :: i_vrt
297 
298  if (this%is_reduced) then
299  i_vrt = this%remote_to_virtual(i_rmt)
300  else
301  i_vrt = i_rmt
302  end if
303  val = this%virtual_mt%adbl1d(i_vrt)
304 
305  end function get_dbl1d
306 
307  function get_array_dbl1d(this) result(array)
308  class(virtualdbl1dtype) :: this
309  real(dp), dimension(:), pointer, contiguous :: array
310 
311  array => this%virtual_mt%adbl1d
312 
313  end function get_array_dbl1d
314 
315  function get_dbl2d(this, j_cmp, i_rmt) result(val)
316  class(virtualdbl2dtype) :: this
317  integer(I4B) :: j_cmp
318  integer(I4B) :: i_rmt
319  real(dp) :: val
320  ! local
321  integer(I4B) :: i_vrt
322 
323  if (this%is_reduced) then
324  i_vrt = this%remote_to_virtual(i_rmt)
325  else
326  i_vrt = i_rmt
327  end if
328  val = this%virtual_mt%adbl2d(j_cmp, i_vrt)
329 
330  end function get_dbl2d
331 
332  function get_array_dbl2d(this) result(array)
333  class(virtualdbl2dtype) :: this
334  real(dp), dimension(:, :), pointer, contiguous :: array
335 
336  array => this%virtual_mt%adbl2d
337 
338  end function get_array_dbl2d
339 
340  function get_virtual_data_from_list(list, idx) result(vd)
341  type(listtype) :: list
342  integer(I4B) :: idx
343  class(virtualdatatype), pointer :: vd
344  ! local
345  class(*), pointer :: obj_ptr
346 
347  vd => null()
348  obj_ptr => list%GetItem(idx)
349  select type (obj_ptr)
350  class is (virtualdatatype)
351  vd => obj_ptr
352  end select
353 
354  end function get_virtual_data_from_list
355 
356 end module virtualbasemodule
This module contains simulation constants.
Definition: Constants.f90:9
integer(i4b), parameter lencomponentname
maximum length of a component name
Definition: Constants.f90:18
integer(i4b), parameter lenvarname
maximum length of a variable name
Definition: Constants.f90:17
integer(i4b), parameter lenmempath
maximum length of the memory path
Definition: Constants.f90:27
This module defines variable data types.
Definition: kind.f90:8
subroutine, public get_from_memorystore(name, mem_path, mt, found, check)
@ brief Get a memory type entry from the memory list
integer(i4b) function, dimension(:), pointer, contiguous get_element_map(this)
Return array with offsets for elements.
subroutine vm_deallocate_int(this)
subroutine vm_allocate_dbl(this, var_name, mem_path, shape)
real(dp) function get_dbl2d(this, j_cmp, i_rmt)
real(dp) function, dimension(:, :), pointer, contiguous get_array_dbl2d(this)
logical(lgp) function vm_check_stage(this, stage)
Check if this data item requires syncing.
integer(i4b) function, dimension(:), pointer, contiguous get_array_int1d(this)
subroutine vm_allocate_dbl2d(this, var_name, mem_path, shape)
class(virtualdatatype) function, pointer, public get_virtual_data_from_list(list, idx)
subroutine vm_allocate_int1d(this, var_name, mem_path, shape)
real(dp) function, dimension(:), pointer, contiguous get_array_dbl1d(this)
subroutine vm_allocate_dbl1d(this, var_name, mem_path, shape)
integer(i4b) function get_int(this)
integer(i4b) function get_int1d(this, i_rmt)
integer(i4b), parameter, public map_conn_type
Definition: VirtualBase.f90:15
integer(i4b), parameter, public map_all_type
Definition: VirtualBase.f90:13
subroutine vm_link(this)
subroutine vm_deallocate_int1d(this)
subroutine vm_allocate_int(this, var_name, mem_path, shape)
subroutine vm_deallocate_dbl1d(this)
integer(i4b), parameter, public nr_vdc_element_maps
Definition: VirtualBase.f90:16
subroutine vm_deallocate_dbl2d(this)
real(dp) function get_dbl(this)
real(dp) function get_dbl1d(this, i_rmt)
subroutine vm_deallocate_dbl(this)
class(virtualdatatype) function, pointer vm_to_base(this)
integer(i4b), parameter, public map_node_type
Definition: VirtualBase.f90:14
A generic heterogeneous doubly-linked list.
Definition: List.f90:14
This is a generic data structure to virtualize pieces of memory in 2 distinct ways:
Definition: VirtualBase.f90:35