MODFLOW 6  version 6.9.0.dev0
USGS Modular Hydrologic Model
MemoryManager.f90
Go to the documentation of this file.
2 
3  use kindmodule, only: dp, lgp, i4b, i8b
4  use constantsmodule, only: dzero, done, &
5  dem3, dem6, dem9, dep3, dep6, dep9, &
11  tabright
12  use simvariablesmodule, only: errmsg
14  use memorytypemodule, only: memorytype
19  use tablemodule, only: tabletype, table_cr
21 
22  implicit none
23  private
24  public :: mem_allocate
25  public :: mem_checkin
26  public :: mem_reallocate
27  public :: mem_setptr
28  public :: mem_copyptr
29  public :: mem_reassignptr
30  public :: mem_deallocate
31  public :: mem_write_usage
32  public :: mem_da
33  public :: mem_set_print_option
34  public :: get_from_memorystore
35 
36  public :: get_mem_type
37  public :: get_mem_rank
38  public :: get_mem_elem_size
39  public :: get_mem_shape
40  public :: get_isize
41  public :: copy_dbl1d
42 
43  public :: memorystore
44  public :: mem_print_detailed
45  public :: mem_release
46 
48  type(tabletype), pointer :: memtab => null()
49  integer(I8B) :: nvalues_alogical = 0
50  integer(I8B) :: nvalues_astr = 0
51  integer(I8B) :: nvalues_aint = 0
52  integer(I8B) :: nvalues_adbl = 0
53  integer(I4B) :: iprmem = 0
54 
55  interface mem_allocate
56  module procedure &
59  allocate_str, &
61  allocate_int, &
65  allocate_dbl, &
70  end interface mem_allocate
71 
72  interface mem_checkin
73  module procedure &
75  checkin_int1d, &
76  checkin_int2d, &
77  checkin_dbl1d, &
78  checkin_dbl2d, &
80  end interface mem_checkin
81 
82  interface mem_reallocate
83  module procedure &
91  end interface mem_reallocate
92 
93  interface mem_setptr
94  module procedure &
97  setptr_int, &
98  setptr_int1d, &
99  setptr_int2d, &
100  setptr_int3d, &
101  setptr_dbl, &
102  setptr_dbl1d, &
103  setptr_dbl2d, &
104  setptr_dbl3d, &
105  setptr_str, &
106  setptr_str1d, &
108  end interface mem_setptr
109 
110  interface mem_copyptr
111  module procedure &
113  copyptr_int1d, &
114  copyptr_int2d, &
115  copyptr_dbl1d, &
117  end interface mem_copyptr
118 
119  interface mem_reassignptr
120  module procedure &
121  reassignptr_int, &
127  end interface mem_reassignptr
128 
129  interface mem_deallocate
130  module procedure &
133  deallocate_str, &
136  deallocate_int, &
140  deallocate_dbl, &
144  end interface mem_deallocate
145 
146 contains
147 
148  !> @ brief Get the variable memory type
149  !!
150  !! Returns any of 'LOGICAL', 'INTEGER', 'DOUBLE', 'STRING'.
151  !! returns 'UNKNOWN' when the variable is not found.
152  !<
153  subroutine get_mem_type(name, mem_path, var_type)
154  character(len=*), intent(in) :: name !< variable name
155  character(len=*), intent(in) :: mem_path !< path where the variable is stored
156  character(len=LENMEMTYPE), intent(out) :: var_type !< memory type
157  ! -- local
158  type(memorytype), pointer :: mt
159  logical(LGP) :: found
160  ! -- code
161  mt => null()
162  var_type = 'UNKNOWN'
163  call get_from_memorystore(name, mem_path, mt, found)
164  if (found) then
165  var_type = mt%memtype
166  end if
167  end subroutine get_mem_type
168 
169  !> @ brief Get the variable rank
170  !!
171  !! Returns rank = -1 when not found.
172  !<
173  subroutine get_mem_rank(name, mem_path, rank)
174  character(len=*), intent(in) :: name !< variable name
175  character(len=*), intent(in) :: mem_path !< mem_path
176  integer(I4B), intent(out) :: rank !< rank
177  ! -- local
178  type(memorytype), pointer :: mt => null()
179  logical(LGP) :: found
180  ! -- code
181  !
182  ! -- initialize rank to a value to communicate failure
183  rank = -1
184  !
185  ! -- get the entry from the memory manager; check=.false. so a missing
186  ! variable returns rank=-1 instead of terminating
187  call get_from_memorystore(name, mem_path, mt, found, check=.false.)
188  !
189  ! -- set rank
190  if (found) then
191  if (associated(mt%logicalsclr)) rank = 0
192  if (associated(mt%intsclr)) rank = 0
193  if (associated(mt%dblsclr)) rank = 0
194  if (associated(mt%alogical1d)) rank = 1
195  if (associated(mt%aint1d)) rank = 1
196  if (associated(mt%aint2d)) rank = 2
197  if (associated(mt%aint3d)) rank = 3
198  if (associated(mt%adbl1d)) rank = 1
199  if (associated(mt%adbl2d)) rank = 2
200  if (associated(mt%adbl3d)) rank = 3
201  if (associated(mt%strsclr)) rank = 0
202  if (associated(mt%astr1d)) rank = 1
203  if (associated(mt%acharstr1d)) rank = 1
204  end if
205  end subroutine get_mem_rank
206 
207  !> @ brief Get the memory size of a single element of the stored variable
208  !!
209  !! Memory size in bytes, returns size = -1 when not found. This is
210  !< also string length.
211  subroutine get_mem_elem_size(name, mem_path, size)
212  character(len=*), intent(in) :: name !< variable name
213  character(len=*), intent(in) :: mem_path !< path where the variable is stored
214  integer(I4B), intent(out) :: size !< size of the variable in bytes
215  ! -- local
216  type(memorytype), pointer :: mt => null()
217  logical(LGP) :: found
218  ! -- code
219  !
220  ! -- initialize size to a value to communicate failure
221  size = -1
222  !
223  ! -- get the entry from the memory manager
224  call get_from_memorystore(name, mem_path, mt, found)
225  !
226  ! -- set memory size
227  if (found) then
228  size = mt%element_size
229  end if
230  end subroutine get_mem_elem_size
231 
232  !> @ brief Get the variable memory shape
233  !!
234  !! Returns an integer array with the shape (Fortran ordering),
235  !! and set shape(1) = -1 when not found.
236  !<
237  subroutine get_mem_shape(name, mem_path, mem_shape)
238  character(len=*), intent(in) :: name !< variable name
239  character(len=*), intent(in) :: mem_path !< path where the variable is stored
240  integer(I4B), dimension(:), intent(out) :: mem_shape !< shape of the variable
241  ! -- local
242  type(memorytype), pointer :: mt => null()
243  logical(LGP) :: found
244  ! -- code
245  !
246  ! -- get the entry from the memory manager
247  call get_from_memorystore(name, mem_path, mt, found)
248  !
249  ! -- set shape
250  if (found) then
251  if (associated(mt%logicalsclr)) mem_shape = shape(mt%logicalsclr)
252  if (associated(mt%intsclr)) mem_shape = shape(mt%logicalsclr)
253  if (associated(mt%dblsclr)) mem_shape = shape(mt%dblsclr)
254  if (associated(mt%alogical1d)) mem_shape = shape(mt%alogical1d)
255  if (associated(mt%aint1d)) mem_shape = shape(mt%aint1d)
256  if (associated(mt%aint2d)) mem_shape = shape(mt%aint2d)
257  if (associated(mt%aint3d)) mem_shape = shape(mt%aint3d)
258  if (associated(mt%adbl1d)) mem_shape = shape(mt%adbl1d)
259  if (associated(mt%adbl2d)) mem_shape = shape(mt%adbl2d)
260  if (associated(mt%adbl3d)) mem_shape = shape(mt%adbl3d)
261  if (associated(mt%strsclr)) mem_shape = shape(mt%strsclr)
262  if (associated(mt%astr1d)) mem_shape = shape(mt%astr1d)
263  if (associated(mt%acharstr1d)) mem_shape = shape(mt%acharstr1d)
264  ! -- to communicate failure
265  else
266  mem_shape(1) = -1
267  end if
268  end subroutine get_mem_shape
269 
270  !> @ brief Get the number of elements for this variable
271  !!
272  !! Returns with isize = -1 when not found.
273  !! Return 1 for scalars.
274  !<
275  subroutine get_isize(name, mem_path, isize)
276  character(len=*), intent(in) :: name !< variable name
277  character(len=*), intent(in) :: mem_path !< path where the variable is stored
278  integer(I4B), intent(out) :: isize !< number of elements (flattened)
279  ! -- local
280  type(memorytype), pointer :: mt => null()
281  logical(LGP) :: found
282  logical(LGP) :: terminate
283  ! -- code
284  !
285  ! -- initialize isize to a value to communicate failure
286  isize = -1
287  !
288  ! -- don't exit program if variable not found
289  terminate = .false.
290  !
291  ! -- get the entry from the memory manager
292  call get_from_memorystore(name, mem_path, mt, found, terminate)
293  !
294  ! -- set isize
295  if (found) then
296  isize = mt%isize
297  end if
298  end subroutine get_isize
299 
300  !> @ brief Get a memory type entry from the memory list
301  !!
302  !! Default value for @par check is .true. which means that this
303  !! routine will kill the program when the memory entry cannot be found.
304  !<
305  subroutine get_from_memorystore(name, mem_path, mt, found, check)
306  character(len=*), intent(in) :: name !< variable name
307  character(len=*), intent(in) :: mem_path !< path where the variable is stored
308  type(memorytype), pointer, intent(inout) :: mt !< memory type entry
309  logical(LGP), intent(out) :: found !< set to .true. when found
310  logical(LGP), intent(in), optional :: check !< to suppress aborting the program when not found,
311  !! set check = .false.
312  ! -- local
313  logical(LGP) check_opt
314  ! -- code
315  mt => memorystore%get(name, mem_path)
316  found = associated(mt)
317 
318  check_opt = .true.
319  if (present(check)) then
320  check_opt = check
321  end if
322  if (check_opt) then
323  if (.not. found) then
324  errmsg = "Programming error in memory manager. Variable '"// &
325  trim(name)//"' in '"//trim(mem_path)//"' cannot be "// &
326  "assigned because it does not exist in memory manager."
327  call store_error(errmsg, terminate=.true.)
328  end if
329  end if
330  end subroutine get_from_memorystore
331 
332  !> @brief Issue allocation error message and stop program execution
333  !<
334  subroutine allocate_error(varname, mem_path, istat, isize)
335  character(len=*), intent(in) :: varname !< variable name
336  character(len=*), intent(in) :: mem_path !< path where the variable is stored
337  integer(I4B), intent(in) :: istat !< status code
338  integer(I4B), intent(in) :: isize !< size of allocation
339  ! -- local
340  character(len=20) :: csize
341  character(len=20) :: cstat
342  ! -- code
343  !
344  ! -- initialize character variables
345  write (csize, '(i0)') isize
346  write (cstat, '(i0)') istat
347  !
348  ! -- create error message
349  errmsg = "Error trying to allocate memory. Path '"//trim(mem_path)// &
350  "' variable name '"//trim(varname)//"' size '"//trim(csize)// &
351  "'. Error message is '"//trim(adjustl(errmsg))// &
352  "'. Status code is "//trim(cstat)//'.'
353  !
354  ! -- store error and stop program execution
355  call store_error(errmsg, terminate=.true.)
356  end subroutine allocate_error
357 
358  !> @brief Allocate a logical scalar
359  !<
360  subroutine allocate_logical(sclr, name, mem_path)
361  logical(LGP), pointer, intent(inout) :: sclr !< variable for allocation
362  character(len=*), intent(in) :: name !< variable name
363  character(len=*), intent(in) :: mem_path !< path where the variable is stored
364  ! -- local
365  integer(I4B) :: istat
366  type(memorytype), pointer :: mt
367  ! -- code
368  !
369  ! -- check variable name length
370  call mem_check_length(name, lenvarname, "variable")
371  !
372  ! -- allocate the logical scalar
373  allocate (sclr, stat=istat, errmsg=errmsg)
374  if (istat /= 0) then
375  call allocate_error(name, mem_path, istat, 1)
376  end if
377  !
378  ! -- update counter
380  !
381  ! -- allocate memory type
382  allocate (mt)
383  !
384  ! -- set memory type
385  mt%logicalsclr => sclr
386  mt%element_size = lgp
387  mt%isize = 1
388  mt%name = name
389  mt%path = mem_path
390  write (mt%memtype, "(a)") 'LOGICAL'
391  !
392  ! -- add memory type to the memory list
393  call memorystore%add(mt)
394  end subroutine allocate_logical
395 
396  !> @brief Allocate a 1-dimensional logical array
397  !<
398  subroutine allocate_logical1d(alog, nrow, name, mem_path)
399  logical(LGP), dimension(:), pointer, contiguous, intent(inout) :: alog !< variable for allocation
400  integer(I4B), intent(in) :: nrow !< number of rows
401  character(len=*), intent(in) :: name !< variable name
402  character(len=*), intent(in) :: mem_path !< path where variable is stored
403  ! --local
404  type(memorytype), pointer :: mt
405  integer(I4B) :: istat
406  integer(I4B) :: isize
407  ! -- code
408  !
409  ! -- check variable name length
410  call mem_check_length(name, lenvarname, "variable")
411  !
412  ! -- set isize
413  isize = nrow
414  !
415  ! -- allocate logical array
416  allocate (alog(nrow), stat=istat, errmsg=errmsg)
417  if (istat /= 0) then
418  call allocate_error(name, mem_path, istat, isize)
419  end if
420  !
421  ! -- update counter
423  !
424  ! -- allocate memory type
425  allocate (mt)
426  !
427  ! -- set memory type
428  mt%alogical1d => alog
429  mt%element_size = lgp
430  mt%isize = isize
431  mt%name = name
432  mt%path = mem_path
433  write (mt%memtype, "(a,' (',i0,')')") 'LOGICAL', isize
434  !
435  ! -- add memory type to the memory list
436  call memorystore%add(mt)
437  end subroutine allocate_logical1d
438 
439  !> @brief Allocate a character string
440  !<
441  subroutine allocate_str(sclr, ilen, name, mem_path)
442  integer(I4B), intent(in) :: ilen !< string length
443  character(len=ilen), pointer, intent(inout) :: sclr !< variable for allocation
444  character(len=*), intent(in) :: name !< variable name
445  character(len=*), intent(in) :: mem_path !< path where the variable is stored
446  ! -- local
447  integer(I4B) :: istat
448  type(memorytype), pointer :: mt
449  ! -- format
450  ! -- code
451  !
452  ! -- make sure ilen is greater than 0
453  if (ilen < 1) then
454  errmsg = 'Programming error in allocate_str. ILEN must be greater than 0.'
455  call store_error(errmsg, terminate=.true.)
456  end if
457  !
458  ! -- check variable name length
459  call mem_check_length(name, lenvarname, "variable")
460  !
461  ! -- allocate string
462  allocate (character(len=ilen) :: sclr, stat=istat, errmsg=errmsg)
463  if (istat /= 0) then
464  call allocate_error(name, mem_path, istat, 1)
465  end if
466  !
467  ! -- set sclr to a empty string
468  sclr = ' '
469  !
470  ! -- update counter
471  nvalues_astr = nvalues_astr + ilen
472  !
473  ! -- allocate memory type
474  allocate (mt)
475  !
476  ! -- set memory type
477  mt%strsclr => sclr
478  mt%element_size = ilen
479  mt%isize = 1
480  mt%name = name
481  mt%path = mem_path
482  write (mt%memtype, "(a,' LEN=',i0)") 'STRING', ilen
483  !
484  ! -- add defined length string to the memory manager list
485  call memorystore%add(mt)
486  end subroutine allocate_str
487 
488  !> @brief Allocate a 1-dimensional defined length string array
489  !<
490  subroutine allocate_str1d(astr1d, ilen, nrow, name, mem_path)
491  integer(I4B), intent(in) :: ilen !< string length
492  character(len=ilen), dimension(:), &
493  pointer, contiguous, intent(inout) :: astr1d !< variable for allocation
494  integer(I4B), intent(in) :: nrow !< number of strings in array
495  character(len=*), intent(in) :: name !< variable name
496  character(len=*), intent(in) :: mem_path !< path where the variable is stored
497  ! -- local variables
498  type(memorytype), pointer :: mt
499  character(len=ilen) :: string
500  integer(I4B) :: n
501  integer(I4B) :: istat
502  integer(I4B) :: isize
503  ! -- code
504  !
505  ! -- initialize string
506  string = ''
507  !
508  ! -- make sure ilen is greater than 0
509  if (ilen < 1) then
510  errmsg = 'Programming error in allocate_str1d. '// &
511  'ILEN must be greater than 0.'
512  call store_error(errmsg, terminate=.true.)
513  end if
514  !
515  ! -- check variable name length
516  call mem_check_length(name, lenvarname, "variable")
517  !
518  ! -- calculate isize
519  isize = nrow
520  !
521  ! -- allocate defined length string array
522  allocate (character(len=ilen) :: astr1d(nrow), stat=istat, errmsg=errmsg)
523  !
524  ! -- check for error condition
525  if (istat /= 0) then
526  call allocate_error(name, mem_path, istat, isize)
527  end if
528  !
529  ! -- fill deferred length string with empty string
530  do n = 1, nrow
531  astr1d(n) = string
532  end do
533  !
534  ! -- update counter
535  nvalues_astr = nvalues_astr + isize
536  !
537  ! -- allocate memory type
538  allocate (mt)
539  !
540  ! -- set memory type
541  mt%astr1d => astr1d
542  mt%element_size = ilen
543  mt%isize = isize
544  mt%name = name
545  mt%path = mem_path
546  write (mt%memtype, "(a,' LEN=',i0,' (',i0,')')") 'STRING', ilen, nrow
547  !
548  ! -- add deferred length character array to the memory manager list
549  call memorystore%add(mt)
550  end subroutine allocate_str1d
551 
552  !> @brief Allocate a 1-dimensional array of deferred-length CharacterStringType
553  !<
554  subroutine allocate_charstr1d(acharstr1d, ilen, nrow, name, mem_path)
555  type(characterstringtype), dimension(:), &
556  pointer, contiguous, intent(inout) :: acharstr1d !< variable for allocation
557  integer(I4B), intent(in) :: ilen !< string length
558  integer(I4B), intent(in) :: nrow !< number of strings in array
559  character(len=*), intent(in) :: name !< variable name
560  character(len=*), intent(in) :: mem_path !< path where the variable is stored
561  ! -- local variables
562  character(len=ilen) :: string
563  type(memorytype), pointer :: mt
564  integer(I4B) :: n
565  integer(I4B) :: istat
566  integer(I4B) :: isize
567  ! -- code
568  !
569  ! -- initialize string
570  string = ''
571  !
572  ! -- check variable name length
573  call mem_check_length(name, lenvarname, "variable")
574  !
575  ! -- calculate isize
576  isize = nrow
577  !
578  ! -- allocate deferred length string array
579  allocate (acharstr1d(nrow), stat=istat, errmsg=errmsg)
580  !
581  ! -- check for error condition
582  if (istat /= 0) then
583  call allocate_error(name, mem_path, istat, isize)
584  end if
585  !
586  ! -- fill deferred length string with empty string
587  do n = 1, nrow
588  acharstr1d(n) = string
589  end do
590  !
591  ! -- update counter
592  nvalues_astr = nvalues_astr + isize
593  !
594  ! -- allocate memory type
595  allocate (mt)
596  !
597  ! -- set memory type
598  mt%acharstr1d => acharstr1d
599  mt%element_size = ilen
600  mt%isize = isize
601  mt%name = name
602  mt%path = mem_path
603  write (mt%memtype, "(a,' LEN=',i0,' (',i0,')')") 'STRING', ilen, nrow
604  !
605  ! -- add deferred length character array to the memory manager list
606  call memorystore%add(mt)
607  end subroutine allocate_charstr1d
608 
609  !> @brief Allocate a integer scalar
610  !<
611  subroutine allocate_int(sclr, name, mem_path)
612  integer(I4B), pointer, intent(inout) :: sclr !< variable for allocation
613  character(len=*), intent(in) :: name !< variable name
614  character(len=*), intent(in) :: mem_path !< path where the variable is stored
615  ! -- local
616  type(memorytype), pointer :: mt
617  integer(I4B) :: istat
618  ! -- code
619  !
620  ! -- check variable name length
621  call mem_check_length(name, lenvarname, "variable")
622  !
623  ! -- allocate integer scalar
624  allocate (sclr, stat=istat, errmsg=errmsg)
625  if (istat /= 0) then
626  call allocate_error(name, mem_path, istat, 1)
627  end if
628  !
629  ! -- update counter
631  !
632  ! -- allocate memory type
633  allocate (mt)
634  !
635  ! -- set memory type
636  mt%intsclr => sclr
637  mt%element_size = i4b
638  mt%isize = 1
639  mt%name = name
640  mt%path = mem_path
641  write (mt%memtype, "(a)") 'INTEGER'
642  !
643  ! -- add memory type to the memory list
644  call memorystore%add(mt)
645  end subroutine allocate_int
646 
647  !> @brief Allocate a 1-dimensional integer array
648  !<
649  subroutine allocate_int1d(aint, nrow, name, mem_path)
650  integer(I4B), dimension(:), pointer, contiguous, intent(inout) :: aint !< variable for allocation
651  integer(I4B), intent(in) :: nrow !< integer array number of rows
652  character(len=*), intent(in) :: name !< variable name
653  character(len=*), intent(in) :: mem_path !< path where variable is stored
654  ! --local
655  type(memorytype), pointer :: mt
656  integer(I4B) :: istat
657  integer(I4B) :: isize
658  ! -- code
659  !
660  ! -- check variable name length
661  call mem_check_length(name, lenvarname, "variable")
662  !
663  ! -- set isize
664  isize = nrow
665  !
666  ! -- allocate integer array
667  allocate (aint(nrow), stat=istat, errmsg=errmsg)
668  if (istat /= 0) then
669  call allocate_error(name, mem_path, istat, isize)
670  end if
671  !
672  ! -- update counter
673  nvalues_aint = nvalues_aint + isize
674  !
675  ! -- allocate memory type
676  allocate (mt)
677  !
678  ! -- set memory type
679  mt%aint1d => aint
680  mt%element_size = i4b
681  mt%isize = isize
682  mt%name = name
683  mt%path = mem_path
684  write (mt%memtype, "(a,' (',i0,')')") 'INTEGER', isize
685  !
686  ! -- add memory type to the memory list
687  call memorystore%add(mt)
688  end subroutine allocate_int1d
689 
690  !> @brief Allocate a 2-dimensional integer array
691  !<
692  subroutine allocate_int2d(aint, ncol, nrow, name, mem_path)
693  integer(I4B), dimension(:, :), pointer, contiguous, intent(inout) :: aint !< variable for allocation
694  integer(I4B), intent(in) :: ncol !< number of columns
695  integer(I4B), intent(in) :: nrow !< number of rows
696  character(len=*), intent(in) :: name !< variable name
697  character(len=*), intent(in) :: mem_path !< path where variable is stored
698  ! -- local
699  type(memorytype), pointer :: mt
700  integer(I4B) :: istat
701  integer(I4B) :: isize
702  ! -- code
703  !
704  ! -- check the variable name length
705  call mem_check_length(name, lenvarname, "variable")
706  !
707  ! -- set isize
708  isize = ncol * nrow
709  !
710  ! -- allocate the integer array
711  allocate (aint(ncol, nrow), stat=istat, errmsg=errmsg)
712  if (istat /= 0) then
713  call allocate_error(name, mem_path, istat, isize)
714  end if
715  !
716  ! -- update the counter
717  nvalues_aint = nvalues_aint + isize
718  !
719  ! -- allocate memory type
720  allocate (mt)
721  !
722  ! -- set memory type
723  mt%aint2d => aint
724  mt%element_size = i4b
725  mt%isize = isize
726  mt%name = name
727  mt%path = mem_path
728  write (mt%memtype, "(a,' (',i0,',',i0,')')") 'INTEGER', ncol, nrow
729  !
730  ! -- add memory type to the memory list
731  call memorystore%add(mt)
732  end subroutine allocate_int2d
733 
734  !> @brief Allocate a 3-dimensional integer array
735  !<
736  subroutine allocate_int3d(aint, ncol, nrow, nlay, name, mem_path)
737  integer(I4B), dimension(:, :, :), pointer, contiguous, intent(inout) :: aint !< variable for allocation
738  integer(I4B), intent(in) :: ncol !< number of columns
739  integer(I4B), intent(in) :: nrow !< number of rows
740  integer(I4B), intent(in) :: nlay !< number of layers
741  character(len=*), intent(in) :: name !< variable name
742  character(len=*), intent(in) :: mem_path !< path where variable is stored
743  ! -- local
744  type(memorytype), pointer :: mt
745  integer(I4B) :: istat
746  integer(I4B) :: isize
747  ! -- code
748  !
749  ! -- check variable name length
750  call mem_check_length(name, lenvarname, "variable")
751  !
752  ! -- set isize
753  isize = ncol * nrow * nlay
754  !
755  ! -- allocate integer array
756  allocate (aint(ncol, nrow, nlay), stat=istat, errmsg=errmsg)
757  if (istat /= 0) then
758  call allocate_error(name, mem_path, istat, isize)
759  end if
760  !
761  ! -- update counter
762  nvalues_aint = nvalues_aint + isize
763  !
764  ! -- allocate memory type
765  allocate (mt)
766  !
767  ! -- set memory type
768  mt%aint3d => aint
769  mt%element_size = i4b
770  mt%isize = isize
771  mt%name = name
772  mt%path = mem_path
773  write (mt%memtype, "(a,' (',i0,',',i0,',',i0,')')") 'INTEGER', ncol, &
774  nrow, nlay
775  !
776  ! -- add memory type to the memory list
777  call memorystore%add(mt)
778  end subroutine allocate_int3d
779 
780  !> @brief Allocate a real scalar
781  !<
782  subroutine allocate_dbl(sclr, name, mem_path)
783  real(DP), pointer, intent(inout) :: sclr !< variable for allocation
784  character(len=*), intent(in) :: name !< variable name
785  character(len=*), intent(in) :: mem_path !< path where variable is stored
786  ! -- local
787  type(memorytype), pointer :: mt
788  integer(I4B) :: istat
789  ! -- code
790  !
791  ! -- check variable name length
792  call mem_check_length(name, lenvarname, "variable")
793  !
794  ! -- allocate real scalar
795  allocate (sclr, stat=istat, errmsg=errmsg)
796  if (istat /= 0) then
797  call allocate_error(name, mem_path, istat, 1)
798  end if
799  !
800  ! -- update counter
802  !
803  ! -- allocate memory type
804  allocate (mt)
805  !
806  ! -- set memory type
807  mt%dblsclr => sclr
808  mt%element_size = dp
809  mt%isize = 1
810  mt%name = name
811  mt%path = mem_path
812  write (mt%memtype, "(a)") 'DOUBLE'
813  !
814  ! -- add memory type to the memory list
815  call memorystore%add(mt)
816  end subroutine allocate_dbl
817 
818  !> @brief Allocate a 1-dimensional real array
819  !<
820  subroutine allocate_dbl1d(adbl, nrow, name, mem_path)
821  real(DP), dimension(:), pointer, contiguous, intent(inout) :: adbl !< variable for allocation
822  integer(I4B), intent(in) :: nrow !< number of rows
823  character(len=*), intent(in) :: name !< variable name
824  character(len=*), intent(in) :: mem_path !< path where variable is stored
825  ! -- local
826  type(memorytype), pointer :: mt
827  integer(I4B) :: istat
828  integer(I4B) :: isize
829  ! -- code
830  !
831  ! -- check the variable name length
832  call mem_check_length(name, lenvarname, "variable")
833  !
834  ! -- set isize
835  isize = nrow
836  !
837  ! -- allocate the real array
838  allocate (adbl(nrow), stat=istat, errmsg=errmsg)
839  if (istat /= 0) then
840  call allocate_error(name, mem_path, istat, isize)
841  end if
842  !
843  ! -- update counter
844  nvalues_adbl = nvalues_adbl + isize
845  !
846  ! -- allocate memory type
847  allocate (mt)
848  !
849  ! -- set memory type
850  mt%adbl1d => adbl
851  mt%element_size = dp
852  mt%isize = isize
853  mt%name = name
854  mt%path = mem_path
855  write (mt%memtype, "(a,' (',i0,')')") 'DOUBLE', isize
856  !
857  ! -- add memory type to the memory list
858  call memorystore%add(mt)
859  end subroutine allocate_dbl1d
860 
861  !> @brief Allocate a 2-dimensional real array
862  !<
863  subroutine allocate_dbl2d(adbl, ncol, nrow, name, mem_path)
864  real(DP), dimension(:, :), pointer, contiguous, intent(inout) :: adbl !< variable for allocation
865  integer(I4B), intent(in) :: ncol !< number of columns
866  integer(I4B), intent(in) :: nrow !< number of rows
867  character(len=*), intent(in) :: name !< variable name
868  character(len=*), intent(in) :: mem_path !< path where variable is stored
869  ! -- local
870  type(memorytype), pointer :: mt
871  integer(I4B) :: istat
872  integer(I4B) :: isize
873  ! -- code
874  !
875  ! -- check the variable name length
876  call mem_check_length(name, lenvarname, "variable")
877  !
878  ! -- set isize
879  isize = ncol * nrow
880  !
881  ! -- allocate the real array
882  allocate (adbl(ncol, nrow), stat=istat, errmsg=errmsg)
883  if (istat /= 0) then
884  call allocate_error(name, mem_path, istat, isize)
885  end if
886  !
887  ! -- update counter
888  nvalues_adbl = nvalues_adbl + isize
889  !
890  ! -- allocate memory type
891  allocate (mt)
892  !
893  ! -- set memory type
894  mt%adbl2d => adbl
895  mt%element_size = dp
896  mt%isize = isize
897  mt%name = name
898  mt%path = mem_path
899  write (mt%memtype, "(a,' (',i0,',',i0,')')") 'DOUBLE', ncol, nrow
900  !
901  ! -- add memory type to the memory list
902  call memorystore%add(mt)
903  end subroutine allocate_dbl2d
904 
905  !> @brief Allocate a 3-dimensional real array
906  !<
907  subroutine allocate_dbl3d(adbl, ncol, nrow, nlay, name, mem_path)
908  real(DP), dimension(:, :, :), pointer, contiguous, intent(inout) :: adbl !< variable for allocation
909  integer(I4B), intent(in) :: ncol !< number of columns
910  integer(I4B), intent(in) :: nrow !< number of rows
911  integer(I4B), intent(in) :: nlay !< number of layers
912  character(len=*), intent(in) :: name !< variable name
913  character(len=*), intent(in) :: mem_path !< path where variable is stored
914  ! -- local
915  type(memorytype), pointer :: mt
916  integer(I4B) :: istat
917  integer(I4B) :: isize
918  ! -- code
919  !
920  ! -- check the variable name length
921  call mem_check_length(name, lenvarname, "variable")
922  !
923  ! -- set isize
924  isize = ncol * nrow * nlay
925  !
926  ! -- allocate the real array
927  allocate (adbl(ncol, nrow, nlay), stat=istat, errmsg=errmsg)
928  if (istat /= 0) then
929  call allocate_error(name, mem_path, istat, isize)
930  end if
931  !
932  ! -- update the counter
933  nvalues_adbl = nvalues_adbl + isize
934  !
935  ! -- allocate memory type
936  allocate (mt)
937  !
938  ! -- set memory type
939  mt%adbl3d => adbl
940  mt%element_size = dp
941  mt%isize = isize
942  mt%name = name
943  mt%path = mem_path
944  write (mt%memtype, "(a,' (',i0,',',i0,',',i0,')')") 'DOUBLE', ncol, &
945  nrow, nlay
946  !
947  ! -- add memory type to the memory list
948  call memorystore%add(mt)
949  end subroutine allocate_dbl3d
950 
951  !> @brief Check in an existing 1d logical array with a new address (name + path)
952  !<
953  subroutine checkin_logical1d(alog, name, mem_path, name2, mem_path2)
954  logical(LGP), dimension(:), pointer, contiguous, intent(in) :: alog !< the existing array
955  character(len=*), intent(in) :: name !< new variable name
956  character(len=*), intent(in) :: mem_path !< new path where variable is stored
957  character(len=*), intent(in) :: name2 !< existing variable name
958  character(len=*), intent(in) :: mem_path2 !< existing path where variable is stored
959  ! --local
960  type(memorytype), pointer :: mt
961  integer(I4B) :: isize
962  ! -- code
963  !
964  ! -- check variable name length
965  call mem_check_length(name, lenvarname, "variable")
966  !
967  ! -- set isize
968  isize = size(alog)
969  !
970  ! -- allocate memory type
971  allocate (mt)
972  !
973  ! -- set memory type
974  mt%alogical1d => alog
975  mt%element_size = lgp
976  mt%isize = isize
977  mt%name = name
978  mt%path = mem_path
979  write (mt%memtype, "(a,' (',i0,')')") 'LOGICAL', isize
980  !
981  ! -- set master information
982  mt%master = .false.
983  mt%mastername = name2
984  mt%masterPath = mem_path2
985  !
986  ! -- add memory type to the memory list
987  call memorystore%add(mt)
988  end subroutine checkin_logical1d
989 
990  !> @brief Check in an existing 1d integer array with a new address (name + path)
991  !<
992  subroutine checkin_int1d(aint, name, mem_path, name2, mem_path2)
993  integer(I4B), dimension(:), pointer, contiguous, intent(in) :: aint !< the existing array
994  character(len=*), intent(in) :: name !< new variable name
995  character(len=*), intent(in) :: mem_path !< new path where variable is stored
996  character(len=*), intent(in) :: name2 !< existing variable name
997  character(len=*), intent(in) :: mem_path2 !< existing path where variable is stored
998  ! --local
999  type(memorytype), pointer :: mt
1000  integer(I4B) :: isize
1001  ! -- code
1002  !
1003  ! -- check variable name length
1004  call mem_check_length(name, lenvarname, "variable")
1005  !
1006  ! -- set isize
1007  isize = size(aint)
1008  !
1009  ! -- allocate memory type
1010  allocate (mt)
1011  !
1012  ! -- set memory type
1013  mt%aint1d => aint
1014  mt%element_size = i4b
1015  mt%isize = isize
1016  mt%name = name
1017  mt%path = mem_path
1018  write (mt%memtype, "(a,' (',i0,')')") 'INTEGER', isize
1019  !
1020  ! -- set master information
1021  mt%master = .false.
1022  mt%mastername = name2
1023  mt%masterPath = mem_path2
1024  !
1025  ! -- add memory type to the memory list
1026  call memorystore%add(mt)
1027  end subroutine checkin_int1d
1028 
1029  !> @brief Check in an existing 2d integer array with a new address (name + path)
1030  !<
1031  subroutine checkin_int2d(aint2d, name, mem_path, name2, mem_path2)
1032  integer(I4B), dimension(:, :), pointer, contiguous, intent(inout) :: aint2d !< the existing 2d array
1033  character(len=*), intent(in) :: name !< new variable name
1034  character(len=*), intent(in) :: mem_path !< new path where variable is stored
1035  character(len=*), intent(in) :: name2 !< existing variable name
1036  character(len=*), intent(in) :: mem_path2 !< existing path where variable is stored
1037  ! -- local
1038  type(memorytype), pointer :: mt
1039  integer(I4B) :: ncol, nrow, isize
1040  ! -- code
1041  !
1042  ! -- check the variable name length
1043  call mem_check_length(name, lenvarname, "variable")
1044  !
1045  ! -- set isize
1046  ncol = size(aint2d, dim=1)
1047  nrow = size(aint2d, dim=2)
1048  isize = ncol * nrow
1049  !
1050  ! -- allocate memory type
1051  allocate (mt)
1052  !
1053  ! -- set memory type
1054  mt%aint2d => aint2d
1055  mt%isize = isize
1056  mt%name = name
1057  mt%path = mem_path
1058  write (mt%memtype, "(a,' (',i0,',',i0,')')") 'INTEGER', ncol, nrow
1059  !
1060  ! -- set master information
1061  mt%master = .false.
1062  mt%mastername = name2
1063  mt%masterPath = mem_path2
1064  !
1065  ! -- add memory type to the memory list
1066  call memorystore%add(mt)
1067  end subroutine checkin_int2d
1068 
1069  !> @brief Check in an existing 1d double precision array with a new address (name + path)
1070  !<
1071  subroutine checkin_dbl1d(adbl, name, mem_path, name2, mem_path2)
1072  real(DP), dimension(:), pointer, contiguous, intent(inout) :: adbl !< the existing array
1073  character(len=*), intent(in) :: name !< new variable name
1074  character(len=*), intent(in) :: mem_path !< new path where variable is stored
1075  character(len=*), intent(in) :: name2 !< existing variable name
1076  character(len=*), intent(in) :: mem_path2 !< existing path where variable is stored
1077  ! -- local
1078  type(memorytype), pointer :: mt
1079  integer(I4B) :: isize
1080  ! -- code
1081  !
1082  ! -- check the variable name length
1083  call mem_check_length(name, lenvarname, "variable")
1084  !
1085  ! -- set isize
1086  isize = size(adbl)
1087  !
1088  ! -- allocate memory type
1089  allocate (mt)
1090  !
1091  ! -- set memory type
1092  mt%adbl1d => adbl
1093  mt%element_size = dp
1094  mt%isize = isize
1095  mt%name = name
1096  mt%path = mem_path
1097  write (mt%memtype, "(a,' (',i0,')')") 'DOUBLE', isize
1098  !
1099  ! -- set master information
1100  mt%master = .false.
1101  mt%mastername = name2
1102  mt%masterPath = mem_path2
1103  !
1104  ! -- add memory type to the memory list
1105  call memorystore%add(mt)
1106  end subroutine checkin_dbl1d
1107 
1108  !> @brief Check in an existing 2d double precision array with a new address (name + path)
1109  !<
1110  subroutine checkin_dbl2d(adbl2d, name, mem_path, name2, mem_path2)
1111  real(DP), dimension(:, :), pointer, contiguous, intent(inout) :: adbl2d !< the existing 2d array
1112  character(len=*), intent(in) :: name !< new variable name
1113  character(len=*), intent(in) :: mem_path !< new path where variable is stored
1114  character(len=*), intent(in) :: name2 !< existing variable name
1115  character(len=*), intent(in) :: mem_path2 !< existing path where variable is stored
1116  ! -- local
1117  type(memorytype), pointer :: mt
1118  integer(I4B) :: ncol, nrow, isize
1119  ! -- code
1120  !
1121  ! -- check the variable name length
1122  call mem_check_length(name, lenvarname, "variable")
1123  !
1124  ! -- set isize
1125  ncol = size(adbl2d, dim=1)
1126  nrow = size(adbl2d, dim=2)
1127  isize = ncol * nrow
1128  !
1129  ! -- allocate memory type
1130  allocate (mt)
1131  !
1132  ! -- set memory type
1133  mt%adbl2d => adbl2d
1134  mt%isize = isize
1135  mt%name = name
1136  mt%path = mem_path
1137  write (mt%memtype, "(a,' (',i0,',',i0,')')") 'DOUBLE', ncol, nrow
1138  !
1139  ! -- set master information
1140  mt%master = .false.
1141  mt%mastername = name2
1142  mt%masterPath = mem_path2
1143  !
1144  ! -- add memory type to the memory list
1145  call memorystore%add(mt)
1146  end subroutine checkin_dbl2d
1147 
1148  !> @brief Check in an existing 1d CharacterStringType array with a new address (name + path)
1149  !<
1150  subroutine checkin_charstr1d(acharstr1d, ilen, name, mem_path, name2, mem_path2)
1151  type(characterstringtype), dimension(:), &
1152  pointer, contiguous, intent(inout) :: acharstr1d !< the existing array
1153  integer(I4B), intent(in) :: ilen
1154  character(len=*), intent(in) :: name !< new variable name
1155  character(len=*), intent(in) :: mem_path !< new path where variable is stored
1156  character(len=*), intent(in) :: name2 !< existing variable name
1157  character(len=*), intent(in) :: mem_path2 !< existing path where variable is stored
1158  ! --local
1159  type(memorytype), pointer :: mt
1160  integer(I4B) :: isize
1161  ! -- code
1162  !
1163  ! -- check variable name length
1164  call mem_check_length(name, lenvarname, "variable")
1165  !
1166  ! -- set isize
1167  isize = size(acharstr1d)
1168  !
1169  ! -- allocate memory type
1170  allocate (mt)
1171  !
1172  ! -- set memory type
1173  mt%acharstr1d => acharstr1d
1174  mt%element_size = ilen
1175  mt%isize = isize
1176  mt%name = name
1177  mt%path = mem_path
1178  write (mt%memtype, "(a,' LEN=',i0,' (',i0,')')") 'STRING', ilen, isize
1179  !
1180  ! -- set master information
1181  mt%master = .false.
1182  mt%mastername = name2
1183  mt%masterPath = mem_path2
1184  !
1185  ! -- add memory type to the memory list
1186  call memorystore%add(mt)
1187  end subroutine checkin_charstr1d
1188 
1189  !> @brief Reallocate a 1-dimensional defined length string array
1190  !<
1191  subroutine reallocate_str1d(astr, ilen, nrow, name, mem_path)
1192  integer(I4B), intent(in) :: ilen !< string length
1193  integer(I4B), intent(in) :: nrow !< number of rows
1194  character(len=ilen), dimension(:), pointer, contiguous, intent(inout) :: astr !< the reallocated string array
1195  character(len=*), intent(in) :: name !< variable name
1196  character(len=*), intent(in) :: mem_path !< path where variable is stored
1197  ! -- local
1198  type(memorytype), pointer :: mt
1199  logical(LGP) :: found
1200  character(len=ilen), dimension(:), allocatable :: astrtemp
1201  integer(I4B) :: istat
1202  integer(I4B) :: isize
1203  integer(I4B) :: isize_old
1204  integer(I4B) :: nrow_old
1205  integer(I4B) :: n
1206  !
1207  ! -- Find and assign mt
1208  call get_from_memorystore(name, mem_path, mt, found)
1209  !
1210  ! -- reallocate astr1d
1211  if (found) then
1212  isize_old = mt%isize
1213  if (isize_old > 0) then
1214  nrow_old = size(astr)
1215  else
1216  nrow_old = 0
1217  end if
1218  !
1219  ! -- calculate isize
1220  isize = nrow
1221  !
1222  ! -- allocate astrtemp
1223  allocate (astrtemp(nrow), stat=istat, errmsg=errmsg)
1224  if (istat /= 0) then
1225  call allocate_error(name, mem_path, istat, isize)
1226  end if
1227  !
1228  ! -- copy existing values (only up to the new size to handle shrinking)
1229  do n = 1, min(nrow_old, nrow)
1230  astrtemp(n) = astr(n)
1231  end do
1232  !
1233  ! -- fill new values with missing values
1234  do n = nrow_old + 1, nrow
1235  astrtemp(n) = ''
1236  end do
1237  !
1238  ! -- deallocate mt pointer, repoint, recalculate isize
1239  deallocate (astr)
1240  !
1241  ! -- allocate astr1d
1242  allocate (astr(nrow), stat=istat, errmsg=errmsg)
1243  if (istat /= 0) then
1244  call allocate_error(name, mem_path, istat, isize)
1245  end if
1246  !
1247  ! -- fill the reallocate character array
1248  do n = 1, nrow
1249  astr(n) = astrtemp(n)
1250  end do
1251  !
1252  ! -- deallocate temporary storage
1253  deallocate (astrtemp)
1254  !
1255  ! -- reset memory manager values
1256  mt%astr1d => astr
1257  mt%element_size = ilen
1258  mt%isize = isize
1259  mt%nrealloc = mt%nrealloc + 1
1260  mt%master = .true.
1261  nvalues_astr = nvalues_astr + isize - isize_old
1262  write (mt%memtype, "(a,' LEN=',i0,' (',i0,')')") 'STRING', ilen, nrow
1263  else
1264  errmsg = "Programming error, variable '"//trim(name)//"' from '"// &
1265  trim(mem_path)//"' is not defined in the memory manager. Use "// &
1266  "mem_allocate instead."
1267  call store_error(errmsg, terminate=.true.)
1268  end if
1269  end subroutine reallocate_str1d
1270 
1271  !> @brief Reallocate a 1-dimensional deferred length string array
1272  !<
1273  subroutine reallocate_charstr1d(acharstr1d, ilen, nrow, name, mem_path)
1274  type(characterstringtype), dimension(:), pointer, contiguous, &
1275  intent(inout) :: acharstr1d !< the reallocated charstring array
1276  integer(I4B), intent(in) :: ilen !< string length
1277  integer(I4B), intent(in) :: nrow !< number of rows
1278  character(len=*), intent(in) :: name !< variable name
1279  character(len=*), intent(in) :: mem_path !< path where variable is stored
1280  ! -- local
1281  type(memorytype), pointer :: mt
1282  logical(LGP) :: found
1283  type(characterstringtype), dimension(:), allocatable :: astrtemp
1284  character(len=ilen) :: string
1285  integer(I4B) :: istat
1286  integer(I4B) :: isize
1287  integer(I4B) :: isize_old
1288  integer(I4B) :: nrow_old
1289  integer(I4B) :: n
1290  !
1291  ! -- Initialize string
1292  string = ''
1293  !
1294  ! -- Find and assign mt
1295  call get_from_memorystore(name, mem_path, mt, found)
1296  !
1297  ! -- reallocate astr1d
1298  if (found) then
1299  isize_old = mt%isize
1300  if (isize_old > 0) then
1301  nrow_old = size(acharstr1d)
1302  else
1303  nrow_old = 0
1304  end if
1305  !
1306  ! -- calculate isize
1307  isize = nrow
1308  !
1309  ! -- allocate astrtemp
1310  allocate (astrtemp(nrow), stat=istat, errmsg=errmsg)
1311  if (istat /= 0) then
1312  call allocate_error(name, mem_path, istat, isize)
1313  end if
1314  !
1315  ! -- copy existing values (only up to the new size to handle shrinking)
1316  do n = 1, min(nrow_old, nrow)
1317  astrtemp(n) = acharstr1d(n)
1318  call acharstr1d(n)%destroy()
1319  end do
1320  !
1321  ! -- destroy remaining elements if shrinking
1322  do n = nrow + 1, nrow_old
1323  call acharstr1d(n)%destroy()
1324  end do
1325  !
1326  ! -- fill new values with missing values
1327  do n = nrow_old + 1, nrow
1328  astrtemp(n) = string
1329  end do
1330  !
1331  ! -- deallocate mt pointer, repoint, recalculate isize
1332  deallocate (acharstr1d)
1333  !
1334  ! -- allocate astr1d
1335  allocate (acharstr1d(nrow), stat=istat, errmsg=errmsg)
1336  if (istat /= 0) then
1337  call allocate_error(name, mem_path, istat, isize)
1338  end if
1339  !
1340  ! -- fill the reallocated character array
1341  do n = 1, nrow
1342  acharstr1d(n) = astrtemp(n)
1343  call astrtemp(n)%destroy()
1344  end do
1345  !
1346  ! -- deallocate temporary storage
1347  deallocate (astrtemp)
1348  !
1349  ! -- reset memory manager values
1350  mt%acharstr1d => acharstr1d
1351  mt%element_size = ilen
1352  mt%isize = isize
1353  mt%nrealloc = mt%nrealloc + 1
1354  mt%master = .true.
1355  nvalues_astr = nvalues_astr + isize - isize_old
1356  write (mt%memtype, "(a,' LEN=',i0,' (',i0,')')") 'STRING', ilen, nrow
1357  else
1358  errmsg = "Programming error, variable '"//trim(name)//"' from '"// &
1359  trim(mem_path)//"' is not defined in the memory manager. Use "// &
1360  "mem_allocate instead."
1361  call store_error(errmsg, terminate=.true.)
1362  end if
1363  end subroutine reallocate_charstr1d
1364 
1365  !> @brief Reallocate a 1-dimensional logical array
1366  !<
1367  subroutine reallocate_logical1d(alog, nrow, name, mem_path)
1368  logical(LGP), dimension(:), pointer, contiguous, intent(inout) :: alog !< the reallocated logical array
1369  integer(I4B), intent(in) :: nrow !< number of rows
1370  character(len=*), intent(in) :: name !< variable name
1371  character(len=*), intent(in) :: mem_path !< path where variable is stored
1372  ! -- local
1373  type(memorytype), pointer :: mt
1374  logical(LGP) :: found
1375  integer(I4B) :: istat
1376  integer(I4B) :: isize
1377  integer(I4B) :: i
1378  integer(I4B) :: isizeold
1379  integer(I4B) :: ifill
1380  ! -- code
1381  !
1382  ! -- Find and assign mt
1383  call get_from_memorystore(name, mem_path, mt, found)
1384  !
1385  ! -- Allocate aint and then refill
1386  isize = nrow
1387  isizeold = size(mt%alogical1d)
1388  ifill = min(isizeold, isize)
1389  allocate (alog(nrow), stat=istat, errmsg=errmsg)
1390  if (istat /= 0) then
1391  call allocate_error(name, mem_path, istat, isize)
1392  end if
1393  do i = 1, ifill
1394  alog(i) = mt%alogical1d(i)
1395  end do
1396  !
1397  ! -- deallocate mt pointer, repoint, recalculate isize
1398  deallocate (mt%alogical1d)
1399  mt%alogical1d => alog
1400  mt%element_size = lgp
1401  mt%isize = isize
1402  mt%nrealloc = mt%nrealloc + 1
1403  mt%master = .true.
1404  nvalues_alogical = nvalues_alogical + isize - isizeold
1405  end subroutine reallocate_logical1d
1406 
1407  !> @brief Reallocate a 1-dimensional integer array
1408  !<
1409  subroutine reallocate_int1d(aint, nrow, name, mem_path)
1410  integer(I4B), dimension(:), pointer, contiguous, intent(inout) :: aint !< the reallocated integer array
1411  integer(I4B), intent(in) :: nrow !< number of rows
1412  character(len=*), intent(in) :: name !< variable name
1413  character(len=*), intent(in) :: mem_path !< path where variable is stored
1414  ! -- local
1415  type(memorytype), pointer :: mt
1416  logical(LGP) :: found
1417  integer(I4B) :: istat
1418  integer(I4B) :: isize
1419  integer(I4B) :: i
1420  integer(I4B) :: isizeold
1421  integer(I4B) :: ifill
1422  ! -- code
1423  !
1424  ! -- Find and assign mt
1425  call get_from_memorystore(name, mem_path, mt, found)
1426  !
1427  ! -- Allocate aint and then refill
1428  isize = nrow
1429  isizeold = size(mt%aint1d)
1430  ifill = min(isizeold, isize)
1431  allocate (aint(nrow), stat=istat, errmsg=errmsg)
1432  if (istat /= 0) then
1433  call allocate_error(name, mem_path, istat, isize)
1434  end if
1435  do i = 1, ifill
1436  aint(i) = mt%aint1d(i)
1437  end do
1438  !
1439  ! -- deallocate mt pointer, repoint, recalculate isize
1440  deallocate (mt%aint1d)
1441  mt%aint1d => aint
1442  mt%element_size = i4b
1443  mt%isize = isize
1444  mt%nrealloc = mt%nrealloc + 1
1445  mt%master = .true.
1446  nvalues_aint = nvalues_aint + isize - isizeold
1447  end subroutine reallocate_int1d
1448 
1449  !> @brief Reallocate a 2-dimensional integer array
1450  !<
1451  subroutine reallocate_int2d(aint, ncol, nrow, name, mem_path)
1452  integer(I4B), dimension(:, :), pointer, contiguous, intent(inout) :: aint !< the reallocated 2d integer array
1453  integer(I4B), intent(in) :: ncol !< number of columns
1454  integer(I4B), intent(in) :: nrow !< number of rows
1455  character(len=*), intent(in) :: name !< variable name
1456  character(len=*), intent(in) :: mem_path !< path where variable is stored
1457  ! -- local
1458  type(memorytype), pointer :: mt
1459  logical(LGP) :: found
1460  integer(I4B) :: istat
1461  integer(I4B), dimension(2) :: ishape
1462  integer(I4B) :: i
1463  integer(I4B) :: j
1464  integer(I4B) :: isize
1465  integer(I4B) :: isizeold
1466  ! -- code
1467  !
1468  ! -- Find and assign mt
1469  call get_from_memorystore(name, mem_path, mt, found)
1470  !
1471  ! -- Allocate aint and then refill
1472  ishape = shape(mt%aint2d)
1473  isize = nrow * ncol
1474  isizeold = ishape(1) * ishape(2)
1475  allocate (aint(ncol, nrow), stat=istat, errmsg=errmsg)
1476  if (istat /= 0) then
1477  call allocate_error(name, mem_path, istat, isize)
1478  end if
1479  ! Copy only what fits in the new array to handle shrinking
1480  do i = 1, min(ishape(2), nrow)
1481  do j = 1, min(ishape(1), ncol)
1482  aint(j, i) = mt%aint2d(j, i)
1483  end do
1484  end do
1485  !
1486  ! -- deallocate mt pointer, repoint, recalculate isize
1487  deallocate (mt%aint2d)
1488  mt%aint2d => aint
1489  mt%element_size = i4b
1490  mt%isize = isize
1491  mt%nrealloc = mt%nrealloc + 1
1492  mt%master = .true.
1493  nvalues_aint = nvalues_aint + isize - isizeold
1494  write (mt%memtype, "(a,' (',i0,',',i0,')')") 'INTEGER', ncol, nrow
1495  end subroutine reallocate_int2d
1496 
1497  !> @brief Reallocate a 1-dimensional real array
1498  !<
1499  subroutine reallocate_dbl1d(adbl, nrow, name, mem_path)
1500  real(DP), dimension(:), pointer, contiguous, intent(inout) :: adbl !< the reallocated 1d real array
1501  integer(I4B), intent(in) :: nrow !< number of rows
1502  character(len=*), intent(in) :: name !< variable name
1503  character(len=*), intent(in) :: mem_path !< path where variable is stored
1504  ! -- local
1505  type(memorytype), pointer :: mt
1506  integer(I4B) :: istat
1507  integer(I4B) :: isize
1508  integer(I4B) :: i
1509  integer(I4B) :: isizeold
1510  integer(I4B) :: ifill
1511  logical(LGP) :: found
1512  ! -- code
1513  !
1514  ! -- Find and assign mt
1515  call get_from_memorystore(name, mem_path, mt, found)
1516  !
1517  ! -- Allocate adbl and then refill
1518  isize = nrow
1519  isizeold = size(mt%adbl1d)
1520  ifill = min(isizeold, isize)
1521  allocate (adbl(nrow), stat=istat, errmsg=errmsg)
1522  if (istat /= 0) then
1523  call allocate_error(name, mem_path, istat, isize)
1524  end if
1525  do i = 1, ifill
1526  adbl(i) = mt%adbl1d(i)
1527  end do
1528  !
1529  ! -- deallocate mt pointer, repoint, recalculate isize
1530  deallocate (mt%adbl1d)
1531  mt%adbl1d => adbl
1532  mt%element_size = dp
1533  mt%isize = isize
1534  mt%nrealloc = mt%nrealloc + 1
1535  mt%master = .true.
1536  nvalues_adbl = nvalues_adbl + isize - isizeold
1537  write (mt%memtype, "(a,' (',i0,')')") 'DOUBLE', isize
1538  end subroutine reallocate_dbl1d
1539 
1540  !> @brief Reallocate a 2-dimensional real array
1541  !<
1542  subroutine reallocate_dbl2d(adbl, ncol, nrow, name, mem_path)
1543  real(DP), dimension(:, :), pointer, contiguous, intent(inout) :: adbl !< the reallocated 2d real array
1544  integer(I4B), intent(in) :: ncol !< number of columns
1545  integer(I4B), intent(in) :: nrow !< number of rows
1546  character(len=*), intent(in) :: name !< variable name
1547  character(len=*), intent(in) :: mem_path !< path where variable is stored
1548  ! -- local
1549  type(memorytype), pointer :: mt
1550  logical(LGP) :: found
1551  integer(I4B) :: istat
1552  integer(I4B), dimension(2) :: ishape
1553  integer(I4B) :: i
1554  integer(I4B) :: j
1555  integer(I4B) :: isize
1556  integer(I4B) :: isizeold
1557  ! -- code
1558  !
1559  ! -- Find and assign mt
1560  call get_from_memorystore(name, mem_path, mt, found)
1561  !
1562  ! -- Allocate adbl and then refill
1563  ishape = shape(mt%adbl2d)
1564  isize = nrow * ncol
1565  isizeold = ishape(1) * ishape(2)
1566  allocate (adbl(ncol, nrow), stat=istat, errmsg=errmsg)
1567  if (istat /= 0) then
1568  call allocate_error(name, mem_path, istat, isize)
1569  end if
1570  ! Copy only what fits in the new array to handle shrinking
1571  do i = 1, min(ishape(2), nrow)
1572  do j = 1, min(ishape(1), ncol)
1573  adbl(j, i) = mt%adbl2d(j, i)
1574  end do
1575  end do
1576  !
1577  ! -- deallocate mt pointer, repoint, recalculate isize
1578  deallocate (mt%adbl2d)
1579  mt%adbl2d => adbl
1580  mt%element_size = dp
1581  mt%isize = isize
1582  mt%nrealloc = mt%nrealloc + 1
1583  mt%master = .true.
1584  nvalues_adbl = nvalues_adbl + isize - isizeold
1585  write (mt%memtype, "(a,' (',i0,',',i0,')')") 'DOUBLE', ncol, nrow
1586  end subroutine reallocate_dbl2d
1587 
1588  !> @brief Set pointer to a logical scalar
1589  !<
1590  subroutine setptr_logical(sclr, name, mem_path)
1591  logical(LGP), pointer, intent(inout) :: sclr !< pointer to logical scalar
1592  character(len=*), intent(in) :: name !< variable name
1593  character(len=*), intent(in) :: mem_path !< path where variable is stored
1594  ! -- local
1595  type(memorytype), pointer :: mt
1596  logical(LGP) :: found
1597  ! -- code
1598  call get_from_memorystore(name, mem_path, mt, found)
1599  sclr => mt%logicalsclr
1600  end subroutine setptr_logical
1601 
1602  !> @brief Set pointer to integer scalar
1603  !<
1604  subroutine setptr_int(sclr, name, mem_path)
1605  integer(I4B), pointer, intent(inout) :: sclr !< pointer to integer scalar
1606  character(len=*), intent(in) :: name !< variable name
1607  character(len=*), intent(in) :: mem_path !< path where variable is stored
1608  ! -- local
1609  type(memorytype), pointer :: mt
1610  logical(LGP) :: found
1611  ! -- code
1612  call get_from_memorystore(name, mem_path, mt, found)
1613  sclr => mt%intsclr
1614  end subroutine setptr_int
1615 
1616  !> @brief Set pointer to 1d logical array
1617  !<
1618  subroutine setptr_logical1d(alog, name, mem_path)
1619  logical(LGP), dimension(:), pointer, contiguous, intent(inout) :: alog !< pointer to 1d logical array
1620  character(len=*), intent(in) :: name !< variable name
1621  character(len=*), intent(in) :: mem_path !< path where variable is stored
1622  ! -- local
1623  type(memorytype), pointer :: mt
1624  logical(LGP) :: found
1625  ! -- code
1626  call get_from_memorystore(name, mem_path, mt, found)
1627  alog => mt%alogical1d
1628  end subroutine setptr_logical1d
1629 
1630  !> @brief Set pointer to 1d integer array
1631  !<
1632  subroutine setptr_int1d(aint, name, mem_path)
1633  integer(I4B), dimension(:), pointer, contiguous, intent(inout) :: aint !< pointer to 1d integer array
1634  character(len=*), intent(in) :: name !< variable name
1635  character(len=*), intent(in) :: mem_path !< path where variable is stored
1636  ! -- local
1637  type(memorytype), pointer :: mt
1638  logical(LGP) :: found
1639  ! -- code
1640  call get_from_memorystore(name, mem_path, mt, found)
1641  aint => mt%aint1d
1642  end subroutine setptr_int1d
1643 
1644  !> @brief Set pointer to 2d integer array
1645  !<
1646  subroutine setptr_int2d(aint, name, mem_path)
1647  integer(I4B), dimension(:, :), pointer, contiguous, intent(inout) :: aint !< pointer to 2d integer array
1648  character(len=*), intent(in) :: name !< variable name
1649  character(len=*), intent(in) :: mem_path !< path where variable is stored
1650  ! -- local
1651  type(memorytype), pointer :: mt
1652  logical(LGP) :: found
1653  ! -- code
1654  call get_from_memorystore(name, mem_path, mt, found)
1655  aint => mt%aint2d
1656  end subroutine setptr_int2d
1657 
1658  !> @brief Set pointer to 3d integer array
1659  !<
1660  subroutine setptr_int3d(aint, name, mem_path)
1661  integer(I4B), dimension(:, :, :), pointer, contiguous, intent(inout) :: aint !< pointer to 3d integer array
1662  character(len=*), intent(in) :: name !< variable name
1663  character(len=*), intent(in) :: mem_path !< path where variable is stored
1664  ! -- local
1665  type(memorytype), pointer :: mt
1666  logical(LGP) :: found
1667  ! -- code
1668  call get_from_memorystore(name, mem_path, mt, found)
1669  aint => mt%aint3d
1670  end subroutine setptr_int3d
1671 
1672  !> @brief Set pointer to a real scalar
1673  !<
1674  subroutine setptr_dbl(sclr, name, mem_path)
1675  real(DP), pointer, intent(inout) :: sclr !< pointer to a real scalar
1676  character(len=*), intent(in) :: name !< variable name
1677  character(len=*), intent(in) :: mem_path !< path where variable is stored
1678  ! -- local
1679  type(memorytype), pointer :: mt
1680  logical(LGP) :: found
1681  ! -- code
1682  call get_from_memorystore(name, mem_path, mt, found)
1683  sclr => mt%dblsclr
1684  end subroutine setptr_dbl
1685 
1686  !> @brief Set pointer to a 1d real array
1687  !<
1688  subroutine setptr_dbl1d(adbl, name, mem_path)
1689  real(DP), dimension(:), pointer, contiguous, intent(inout) :: adbl !< pointer to 1d real array
1690  character(len=*), intent(in) :: name !< variable name
1691  character(len=*), intent(in) :: mem_path !< path where variable is stored
1692  ! -- local
1693  type(memorytype), pointer :: mt
1694  logical(LGP) :: found
1695  ! -- code
1696  call get_from_memorystore(name, mem_path, mt, found)
1697  adbl => mt%adbl1d
1698  end subroutine setptr_dbl1d
1699 
1700  !> @brief Set pointer to a 2d real array
1701  !<
1702  subroutine setptr_dbl2d(adbl, name, mem_path)
1703  real(DP), dimension(:, :), pointer, contiguous, intent(inout) :: adbl !< pointer to 2d real array
1704  character(len=*), intent(in) :: name !< variable name
1705  character(len=*), intent(in) :: mem_path !< path where variable is stored
1706  ! -- local
1707  type(memorytype), pointer :: mt
1708  logical(LGP) :: found
1709  ! -- code
1710  call get_from_memorystore(name, mem_path, mt, found)
1711  adbl => mt%adbl2d
1712  end subroutine setptr_dbl2d
1713 
1714  !> @brief Set pointer to a 3d real array
1715  !<
1716  subroutine setptr_dbl3d(adbl, name, mem_path)
1717  real(DP), dimension(:, :, :), pointer, contiguous, intent(inout) :: adbl !< pointer to 3d real array
1718  character(len=*), intent(in) :: name !< variable name
1719  character(len=*), intent(in) :: mem_path !< path where variable is stored
1720  ! -- local
1721  type(memorytype), pointer :: mt
1722  logical(LGP) :: found
1723  ! -- code
1724  call get_from_memorystore(name, mem_path, mt, found)
1725  adbl => mt%adbl3d
1726  end subroutine setptr_dbl3d
1727 
1728  !> @brief Set pointer to a string (scalar)
1729  !<
1730  subroutine setptr_str(asrt, name, mem_path)
1731  character(len=:), pointer :: asrt !< pointer to the character string
1732  character(len=*), intent(in) :: name !< variable name
1733  character(len=*), intent(in) :: mem_path !< path where variable is stored
1734  ! -- local
1735  type(memorytype), pointer :: mt
1736  logical(LGP) :: found
1737  ! -- code
1738  call get_from_memorystore(name, mem_path, mt, found)
1739  asrt => mt%strsclr
1740  end subroutine setptr_str
1741 
1742  !> @brief Set pointer to a fixed-length string array
1743  !<
1744  subroutine setptr_str1d(astr1d, name, mem_path)
1745  character(len=:), dimension(:), &
1746  pointer, contiguous, intent(inout) :: astr1d !< pointer to the string array
1747  character(len=*), intent(in) :: name !< variable name
1748  character(len=*), intent(in) :: mem_path !< path where variable is stored
1749  ! -- local
1750  type(memorytype), pointer :: mt
1751  logical(LGP) :: found
1752  ! -- code
1753  call get_from_memorystore(name, mem_path, mt, found)
1754  select type (item => mt%astr1d)
1755  type is (character(*))
1756  astr1d => item
1757  class default
1758  astr1d => null()
1759  end select
1760  end subroutine setptr_str1d
1761 
1762  !> @brief Set pointer to an array of CharacterStringType
1763  !<
1764  subroutine setptr_charstr1d(acharstr1d, name, mem_path)
1765  type(characterstringtype), dimension(:), pointer, contiguous, &
1766  intent(inout) :: acharstr1d !< the reallocated charstring array
1767  character(len=*), intent(in) :: name !< variable name
1768  character(len=*), intent(in) :: mem_path !< path where variable is stored
1769  ! -- local
1770  type(memorytype), pointer :: mt
1771  logical(LGP) :: found
1772  ! -- code
1773  call get_from_memorystore(name, mem_path, mt, found)
1774  acharstr1d => mt%acharstr1d
1775  end subroutine setptr_charstr1d
1776 
1777  !> @brief Make a copy of a 1-dimensional logical array
1778  !<
1779  subroutine copyptr_logical1d(alog, name, mem_path, mem_path_copy)
1780  logical(LGP), dimension(:), pointer, contiguous, intent(inout) :: alog !< returned copy of 1d logical array
1781  character(len=*), intent(in) :: name !< variable name
1782  character(len=*), intent(in) :: mem_path !< path where variable is stored
1783  character(len=*), intent(in), optional :: mem_path_copy !< optional path where the copy will be stored,
1784  !! if passed then the copy is added to the
1785  !! memory manager
1786  ! -- local
1787  type(memorytype), pointer :: mt
1788  logical(LGP) :: found
1789  integer(I4B) :: n
1790  ! -- code
1791  call get_from_memorystore(name, mem_path, mt, found)
1792  alog => null()
1793  ! -- check the copy into the memory manager
1794  if (present(mem_path_copy)) then
1795  call allocate_logical1d(alog, size(mt%alogical1d), mt%name, mem_path_copy)
1796  ! -- create a local copy
1797  else
1798  allocate (alog(size(mt%alogical1d)))
1799  end if
1800  do n = 1, size(mt%alogical1d)
1801  alog(n) = mt%alogical1d(n)
1802  end do
1803  end subroutine copyptr_logical1d
1804 
1805  !> @brief Make a copy of a 1-dimensional integer array
1806  !<
1807  subroutine copyptr_int1d(aint, name, mem_path, mem_path_copy)
1808  integer(I4B), dimension(:), pointer, contiguous, intent(inout) :: aint !< returned copy of 1d integer array
1809  character(len=*), intent(in) :: name !< variable name
1810  character(len=*), intent(in) :: mem_path !< path where variable is stored
1811  character(len=*), intent(in), optional :: mem_path_copy !< optional path where the copy will be stored,
1812  !! if passed then the copy is added to the
1813  !! memory manager
1814  ! -- local
1815  type(memorytype), pointer :: mt
1816  logical(LGP) :: found
1817  integer(I4B) :: n
1818  ! -- code
1819  call get_from_memorystore(name, mem_path, mt, found)
1820  aint => null()
1821  ! -- check the copy into the memory manager
1822  if (present(mem_path_copy)) then
1823  call allocate_int1d(aint, size(mt%aint1d), mt%name, mem_path_copy)
1824  ! -- create a local copy
1825  else
1826  allocate (aint(size(mt%aint1d)))
1827  end if
1828  do n = 1, size(mt%aint1d)
1829  aint(n) = mt%aint1d(n)
1830  end do
1831  end subroutine copyptr_int1d
1832 
1833  !> @brief Make a copy of a 2-dimensional integer array
1834  !<
1835  subroutine copyptr_int2d(aint, name, mem_path, mem_path_copy)
1836  integer(I4B), dimension(:, :), pointer, contiguous, intent(inout) :: aint !< returned copy of 2d integer array
1837  character(len=*), intent(in) :: name !< variable name
1838  character(len=*), intent(in) :: mem_path !< path where variable is stored
1839  character(len=*), intent(in), optional :: mem_path_copy !< optional path where the copy will be stored,
1840  !! if passed then the copy is added to the
1841  !! memory manager
1842  ! -- local
1843  type(memorytype), pointer :: mt
1844  logical(LGP) :: found
1845  integer(I4B) :: i
1846  integer(I4B) :: j
1847  integer(I4B) :: ncol
1848  integer(I4B) :: nrow
1849  ! -- code
1850  call get_from_memorystore(name, mem_path, mt, found)
1851  aint => null()
1852  ncol = size(mt%aint2d, dim=1)
1853  nrow = size(mt%aint2d, dim=2)
1854  ! -- check the copy into the memory manager
1855  if (present(mem_path_copy)) then
1856  call allocate_int2d(aint, ncol, nrow, mt%name, mem_path_copy)
1857  ! -- create a local copy
1858  else
1859  allocate (aint(ncol, nrow))
1860  end if
1861  do i = 1, nrow
1862  do j = 1, ncol
1863  aint(j, i) = mt%aint2d(j, i)
1864  end do
1865  end do
1866  end subroutine copyptr_int2d
1867 
1868  !> @brief Make a copy of a 1-dimensional real array
1869  !<
1870  subroutine copyptr_dbl1d(adbl, name, mem_path, mem_path_copy)
1871  real(DP), dimension(:), pointer, contiguous, intent(inout) :: adbl !< returned copy of 1d real array
1872  character(len=*), intent(in) :: name !< variable name
1873  character(len=*), intent(in) :: mem_path !< path where variable is stored
1874  character(len=*), intent(in), optional :: mem_path_copy !< optional path where the copy will be stored,
1875  !! if passed then the copy is added to the
1876  !! memory manager
1877  ! -- local
1878  type(memorytype), pointer :: mt
1879  logical(LGP) :: found
1880  integer(I4B) :: n
1881  ! -- code
1882  call get_from_memorystore(name, mem_path, mt, found)
1883  adbl => null()
1884  ! -- check the copy into the memory manager
1885  if (present(mem_path_copy)) then
1886  call allocate_dbl1d(adbl, size(mt%adbl1d), mt%name, mem_path_copy)
1887  ! -- create a local copy
1888  else
1889  allocate (adbl(size(mt%adbl1d)))
1890  end if
1891  do n = 1, size(mt%adbl1d)
1892  adbl(n) = mt%adbl1d(n)
1893  end do
1894  end subroutine copyptr_dbl1d
1895 
1896  !> @brief Make a copy of a 2-dimensional real array
1897  !<
1898  subroutine copyptr_dbl2d(adbl, name, mem_path, mem_path_copy)
1899  real(DP), dimension(:, :), pointer, contiguous, intent(inout) :: adbl !< returned copy of 2d real array
1900  character(len=*), intent(in) :: name !< variable name
1901  character(len=*), intent(in) :: mem_path !< path where variable is stored
1902  character(len=*), intent(in), optional :: mem_path_copy !< optional path where the copy will be stored,
1903  !! if passed then the copy is added to the
1904  !! memory manager
1905  ! -- local
1906  type(memorytype), pointer :: mt
1907  logical(LGP) :: found
1908  integer(I4B) :: i
1909  integer(I4B) :: j
1910  integer(I4B) :: ncol
1911  integer(I4B) :: nrow
1912  ! -- code
1913  call get_from_memorystore(name, mem_path, mt, found)
1914  adbl => null()
1915  ncol = size(mt%adbl2d, dim=1)
1916  nrow = size(mt%adbl2d, dim=2)
1917  ! -- check the copy into the memory manager
1918  if (present(mem_path_copy)) then
1919  call allocate_dbl2d(adbl, ncol, nrow, mt%name, mem_path_copy)
1920  ! -- create a local copy
1921  else
1922  allocate (adbl(ncol, nrow))
1923  end if
1924  do i = 1, nrow
1925  do j = 1, ncol
1926  adbl(j, i) = mt%adbl2d(j, i)
1927  end do
1928  end do
1929  end subroutine copyptr_dbl2d
1930 
1931  !> @brief Copy values from a 1-dimensional real array in the memory
1932  !< manager to a passed 1-dimensional real array
1933  subroutine copy_dbl1d(adbl, name, mem_path)
1934  real(dp), dimension(:), intent(inout) :: adbl !< target array
1935  character(len=*), intent(in) :: name !< variable name
1936  character(len=*), intent(in) :: mem_path !< path where variable is stored
1937  ! -- local
1938  type(memorytype), pointer :: mt
1939  logical(LGP) :: found
1940  integer(I4B) :: n
1941  ! -- code
1942  call get_from_memorystore(name, mem_path, mt, found)
1943  do n = 1, size(mt%adbl1d)
1944  adbl(n) = mt%adbl1d(n)
1945  end do
1946  end subroutine copy_dbl1d
1947 
1948  !> @brief Set the pointer for an integer scalar to
1949  !< a target array already stored in the memory manager
1950  subroutine reassignptr_int(sclr, name, mem_path, name_target, mem_path_target)
1951  integer(I4B), pointer, intent(inout) :: sclr !< pointer to integer scalar
1952  character(len=*), intent(in) :: name !< variable name
1953  character(len=*), intent(in) :: mem_path !< path where variable is stored
1954  character(len=*), intent(in) :: name_target !< name of target variable
1955  character(len=*), intent(in) :: mem_path_target !< path where target variable is stored
1956  ! -- local
1957  type(memorytype), pointer :: mt
1958  type(memorytype), pointer :: mt2
1959  logical(LGP) :: found
1960  ! -- code
1961  call get_from_memorystore(name, mem_path, mt, found)
1962  call get_from_memorystore(name_target, mem_path_target, mt2, found)
1963  if (associated(sclr)) then
1965  deallocate (sclr)
1966  end if
1967  sclr => mt2%intsclr
1968  mt%intsclr => sclr
1969  mt%element_size = i4b
1970  mt%isize = 1
1971  write (mt%memtype, "(a,' (',i0,')')") 'INTEGER', mt%isize
1972  !
1973  ! -- set master information
1974  mt%master = .false.
1975  mt%mastername = name_target
1976  mt%masterPath = mem_path_target
1977  end subroutine reassignptr_int
1978 
1979  !> @brief Set the pointer for a 1-dimensional logical array to
1980  !< a target array already stored in the memory manager
1981  subroutine reassignptr_logical1d(alog, name, mem_path, name_target, &
1982  mem_path_target)
1983  logical(LGP), dimension(:), pointer, contiguous, intent(inout) :: alog !< array pointer
1984  character(len=*), intent(in) :: name !< variable name
1985  character(len=*), intent(in) :: mem_path !< path where variable is stored
1986  character(len=*), intent(in) :: name_target !< name of target variable
1987  character(len=*), intent(in) :: mem_path_target !< path where target variable is stored
1988  ! -- local
1989  type(memorytype), pointer :: mt
1990  type(memorytype), pointer :: mt2
1991  logical(LGP) :: found
1992  ! -- code
1993  call get_from_memorystore(name, mem_path, mt, found)
1994  call get_from_memorystore(name_target, mem_path_target, mt2, found)
1995  if (size(alog) > 0) then
1996  nvalues_alogical = nvalues_alogical - size(alog)
1997  deallocate (alog)
1998  end if
1999  alog => mt2%alogical1d
2000  mt%alogical1d => alog
2001  mt%element_size = lgp
2002  mt%isize = size(alog)
2003  write (mt%memtype, "(a,' (',i0,')')") 'LOGICAL', mt%isize
2004  !
2005  ! -- set master information
2006  mt%master = .false.
2007  mt%mastername = name_target
2008  mt%masterPath = mem_path_target
2009  end subroutine reassignptr_logical1d
2010 
2011  !> @brief Set the pointer for a 1-dimensional integer array to
2012  !< a target array already stored in the memory manager
2013  subroutine reassignptr_int1d(aint, name, mem_path, name_target, mem_path_target)
2014  integer(I4B), dimension(:), pointer, contiguous, intent(inout) :: aint !< pointer to 1d integer array
2015  character(len=*), intent(in) :: name !< variable name
2016  character(len=*), intent(in) :: mem_path !< path where variable is stored
2017  character(len=*), intent(in) :: name_target !< name of target variable
2018  character(len=*), intent(in) :: mem_path_target !< path where target variable is stored
2019  ! -- local
2020  type(memorytype), pointer :: mt
2021  type(memorytype), pointer :: mt2
2022  logical(LGP) :: found
2023  ! -- code
2024  call get_from_memorystore(name, mem_path, mt, found)
2025  call get_from_memorystore(name_target, mem_path_target, mt2, found)
2026  if (size(aint) > 0) then
2027  nvalues_aint = nvalues_aint - size(aint)
2028  deallocate (aint)
2029  end if
2030  aint => mt2%aint1d
2031  mt%aint1d => aint
2032  mt%element_size = i4b
2033  mt%isize = size(aint)
2034  write (mt%memtype, "(a,' (',i0,')')") 'INTEGER', mt%isize
2035  !
2036  ! -- set master information
2037  mt%master = .false.
2038  mt%mastername = name_target
2039  mt%masterPath = mem_path_target
2040  end subroutine reassignptr_int1d
2041 
2042  !> @brief Set the pointer for a 2-dimensional integer array to
2043  !< a target array already stored in the memory manager
2044  subroutine reassignptr_int2d(aint, name, mem_path, name_target, mem_path_target)
2045  integer(I4B), dimension(:, :), pointer, contiguous, intent(inout) :: aint !< pointer to 2d integer array
2046  character(len=*), intent(in) :: name !< variable name
2047  character(len=*), intent(in) :: mem_path !< path where variable is stored
2048  character(len=*), intent(in) :: name_target !< name of target variable
2049  character(len=*), intent(in) :: mem_path_target !< path where target variable is stored
2050  ! -- local
2051  type(memorytype), pointer :: mt
2052  type(memorytype), pointer :: mt2
2053  logical(LGP) :: found
2054  integer(I4B) :: ncol
2055  integer(I4B) :: nrow
2056  ! -- code
2057  call get_from_memorystore(name, mem_path, mt, found)
2058  call get_from_memorystore(name_target, mem_path_target, mt2, found)
2059  if (size(aint) > 0) then
2060  nvalues_aint = nvalues_aint - size(aint)
2061  deallocate (aint)
2062  end if
2063  aint => mt2%aint2d
2064  mt%aint2d => aint
2065  mt%element_size = i4b
2066  mt%isize = size(aint)
2067  ncol = size(aint, dim=1)
2068  nrow = size(aint, dim=2)
2069  write (mt%memtype, "(a,' (',i0,',',i0,')')") 'INTEGER', ncol, nrow
2070  !
2071  ! -- set master information
2072  mt%master = .false.
2073  mt%mastername = name_target
2074  mt%masterPath = mem_path_target
2075  end subroutine reassignptr_int2d
2076 
2077  !> @brief Set the pointer for a 1-dimensional real array to
2078  !< a target array already stored in the memory manager
2079  subroutine reassignptr_dbl1d(adbl, name, mem_path, name_target, mem_path_target)
2080  real(DP), dimension(:), pointer, contiguous, intent(inout) :: adbl !< pointer to 1d real array
2081  character(len=*), intent(in) :: name !< variable name
2082  character(len=*), intent(in) :: mem_path !< path where variable is stored
2083  character(len=*), intent(in) :: name_target !< name of target variable
2084  character(len=*), intent(in) :: mem_path_target !< path where target variable is stored
2085  ! -- local
2086  type(memorytype), pointer :: mt
2087  type(memorytype), pointer :: mt2
2088  logical(LGP) :: found
2089  ! -- code
2090  call get_from_memorystore(name, mem_path, mt, found)
2091  call get_from_memorystore(name_target, mem_path_target, mt2, found)
2092  if (size(adbl) > 0) then
2093  nvalues_adbl = nvalues_adbl - size(adbl)
2094  deallocate (adbl)
2095  end if
2096  adbl => mt2%adbl1d
2097  mt%adbl1d => adbl
2098  mt%element_size = dp
2099  mt%isize = size(adbl)
2100  write (mt%memtype, "(a,' (',i0,')')") 'DOUBLE', mt%isize
2101  !
2102  ! -- set master information
2103  mt%master = .false.
2104  mt%mastername = name_target
2105  mt%masterPath = mem_path_target
2106  end subroutine reassignptr_dbl1d
2107 
2108  !> @brief Set the pointer for a 2-dimensional real array to
2109  !< a target array already stored in the memory manager
2110  subroutine reassignptr_dbl2d(adbl, name, mem_path, name_target, mem_path_target)
2111  real(DP), dimension(:, :), pointer, contiguous, intent(inout) :: adbl !< pointer to 2d real array
2112  character(len=*), intent(in) :: name !< variable name
2113  character(len=*), intent(in) :: mem_path !< path where variable is stored
2114  character(len=*), intent(in) :: name_target !< name of target variable
2115  character(len=*), intent(in) :: mem_path_target !< path where target variable is stored
2116  ! -- local
2117  type(memorytype), pointer :: mt
2118  type(memorytype), pointer :: mt2
2119  logical(LGP) :: found
2120  integer(I4B) :: ncol
2121  integer(I4b) :: nrow
2122  ! -- code
2123  call get_from_memorystore(name, mem_path, mt, found)
2124  call get_from_memorystore(name_target, mem_path_target, mt2, found)
2125  if (size(adbl) > 0) then
2126  nvalues_adbl = nvalues_adbl - size(adbl)
2127  deallocate (adbl)
2128  end if
2129  adbl => mt2%adbl2d
2130  mt%adbl2d => adbl
2131  mt%element_size = dp
2132  mt%isize = size(adbl)
2133  ncol = size(adbl, dim=1)
2134  nrow = size(adbl, dim=2)
2135  write (mt%memtype, "(a,' (',i0,',',i0,')')") 'DOUBLE', ncol, nrow
2136  !
2137  ! -- set master information
2138  mt%master = .false.
2139  mt%mastername = name_target
2140  mt%masterPath = mem_path_target
2141  end subroutine reassignptr_dbl2d
2142 
2143  !> @brief DEPRECATED. The memory manager will handle the deallocation of the pointer.
2144  !<
2145  subroutine deallocate_str(sclr, name, mem_path)
2146  character(len=*), pointer, intent(inout) :: sclr !< pointer to string
2147  character(len=*), intent(in), optional :: name !< variable name
2148  character(len=*), intent(in), optional :: mem_path !< path where variable is stored
2149  ! -- code
2150  return
2151  end subroutine deallocate_str
2152 
2153  !> @brief Deallocate an array of defined-length character strings
2154  !!
2155  !<
2156  subroutine deallocate_str1d(astr1d, name, mem_path)
2157  character(len=*), dimension(:), pointer, contiguous, intent(inout) :: astr1d !< array of strings
2158  character(len=*), optional, intent(in) :: name !< variable name
2159  character(len=*), optional, intent(in) :: mem_path !< path where variable is stored
2160  ! -- code
2161  return
2162 
2163  end subroutine deallocate_str1d
2164 
2165  !> @brief DEPRECATED. The memory manager will handle the deallocation of the pointer.
2166  !!
2167  !<
2168  subroutine deallocate_charstr1d(astr1d, name, mem_path)
2169  type(characterstringtype), dimension(:), pointer, contiguous, &
2170  intent(inout) :: astr1d !< array of strings
2171  character(len=*), optional, intent(in) :: name !< variable name
2172  character(len=*), optional, intent(in) :: mem_path !< path where variable is stored
2173  ! -- code
2174  return
2175  end subroutine deallocate_charstr1d
2176 
2177  !> @brief DEPRECATED. The memory manager will handle the deallocation of the pointer.
2178  !<
2179  subroutine deallocate_logical(sclr)
2180  logical(LGP), pointer, intent(inout) :: sclr !< logical scalar to deallocate
2181  ! -- code
2182  return
2183  end subroutine deallocate_logical
2184 
2185  !> @brief DEPRECATED. The memory manager will handle the deallocation of the pointer.
2186  !<
2187  subroutine deallocate_int(sclr)
2188  integer(I4B), pointer, intent(inout) :: sclr !< integer variable to deallocate
2189  ! -- code
2190  return
2191  end subroutine deallocate_int
2192 
2193  !> @brief DEPRECATED. The memory manager will handle the deallocation of the pointer.
2194  !<
2195  subroutine deallocate_dbl(sclr)
2196  real(DP), pointer, intent(inout) :: sclr !< real variable to deallocate
2197  ! -- code
2198  return
2199  end subroutine deallocate_dbl
2200 
2201  !> @brief DEPRECATED. The memory manager will handle the deallocation of the pointer.
2202  !<
2203  subroutine deallocate_logical1d(alog, name, mem_path)
2204  logical(LGP), dimension(:), pointer, contiguous, intent(inout) :: alog !< 1d logical array to deallocate
2205  character(len=*), optional :: name !< variable name
2206  character(len=*), optional :: mem_path !< path where variable is stored
2207  ! -- code
2208  return
2209  end subroutine deallocate_logical1d
2210 
2211  !> @brief DEPRECATED. The memory manager will handle the deallocation of the pointer.
2212  !<
2213  subroutine deallocate_int1d(aint, name, mem_path)
2214  integer(I4B), dimension(:), pointer, contiguous, intent(inout) :: aint !< 1d integer array to deallocate
2215  character(len=*), optional :: name !< variable name
2216  character(len=*), optional :: mem_path !< path where variable is stored
2217  ! -- code
2218  return
2219  end subroutine deallocate_int1d
2220 
2221  !> @brief DEPRECATED. The memory manager will handle the deallocation of the pointer.
2222  !<
2223  subroutine deallocate_int2d(aint, name, mem_path)
2224  integer(I4B), dimension(:, :), pointer, contiguous, intent(inout) :: aint !< 2d integer array to deallocate
2225  character(len=*), optional :: name !< variable name
2226  character(len=*), optional :: mem_path !< path where variable is stored
2227  ! -- code
2228  return
2229  end subroutine deallocate_int2d
2230 
2231  !> @brief DEPRECATED. The memory manager will handle the deallocation of the pointer.
2232  !<
2233  subroutine deallocate_int3d(aint, name, mem_path)
2234  integer(I4B), dimension(:, :, :), pointer, contiguous, intent(inout) :: aint !< 3d integer array to deallocate
2235  character(len=*), optional :: name !< variable name
2236  character(len=*), optional :: mem_path !< path where variable is stored
2237  ! -- code
2238  return
2239  end subroutine deallocate_int3d
2240 
2241  !> @brief DEPRECATED. The memory manager will handle the deallocation of the pointer.
2242  !<
2243  subroutine deallocate_dbl1d(adbl, name, mem_path)
2244  real(DP), dimension(:), pointer, contiguous, intent(inout) :: adbl !< 1d real array to deallocate
2245  character(len=*), optional :: name !< variable name
2246  character(len=*), optional :: mem_path !< path where variable is stored
2247  ! -- code
2248  return
2249  end subroutine deallocate_dbl1d
2250 
2251  !> @brief DEPRECATED. The memory manager will handle the deallocation of the pointer.
2252  !<
2253  subroutine deallocate_dbl2d(adbl, name, mem_path)
2254  real(DP), dimension(:, :), pointer, contiguous, intent(inout) :: adbl !< 2d real array to deallocate
2255  character(len=*), optional :: name !< variable name
2256  character(len=*), optional :: mem_path !< path where variable is stored
2257  ! -- code
2258  return
2259  end subroutine deallocate_dbl2d
2260 
2261  !> @brief DEPRECATED. The memory manager will handle the deallocation of the pointer.
2262  !<
2263  subroutine deallocate_dbl3d(adbl, name, mem_path)
2264  real(DP), dimension(:, :, :), pointer, contiguous, intent(inout) :: adbl !< 3d real array to deallocate
2265  character(len=*), optional :: name !< variable name
2266  character(len=*), optional :: mem_path !< path where variable is stored
2267  ! -- code
2268  return
2269  end subroutine deallocate_dbl3d
2270 
2271  !> @brief Set the memory print option
2272  !<
2273  subroutine mem_set_print_option(iout, keyword, error_msg)
2274  integer(I4B), intent(in) :: iout !< unit number for mfsim.lst
2275  character(len=*), intent(in) :: keyword !< memory print option
2276  character(len=*), intent(inout) :: error_msg !< returned error message if keyword is not valid option
2277  ! -- local
2278  ! -- format
2279  ! -- code
2280  select case (keyword)
2281  case ('NONE')
2282  iprmem = 0
2283  write (iout, '(4x, a)') &
2284  'LIMITED MEMORY INFORMATION WILL BE WRITTEN.'
2285  case ('SUMMARY')
2286  iprmem = 1
2287  write (iout, '(4x, a)') &
2288  'A SUMMARY OF SIMULATION MEMORY INFORMATION WILL BE WRITTEN.'
2289  case ('ALL')
2290  iprmem = 2
2291  write (iout, '(4x, a)') &
2292  'ALL SIMULATION MEMORY INFORMATION WILL BE WRITTEN.'
2293  case default
2294  error_msg = "Unknown memory print option '"//trim(keyword)//"."
2295  end select
2296  end subroutine mem_set_print_option
2297 
2298  !> @brief Create a table if memory_print_option is 'SUMMARY'
2299  !<
2300  subroutine mem_summary_table(iout, nrows, cunits)
2301  integer(I4B), intent(in) :: iout !< unit number for mfsim.lst
2302  integer(I4B), intent(in) :: nrows !< number of table rows
2303  character(len=*), intent(in) :: cunits !< memory units (bytes, kilobytes, megabytes, or gigabytes)
2304  ! -- local
2305  character(len=LINELENGTH) :: title
2306  character(len=LINELENGTH) :: text
2307  integer(I4B) :: nterms
2308  ! -- formats
2309  ! -- code
2310  nterms = 6
2311  !
2312  ! -- set up table title
2313  title = 'SUMMARY INFORMATION ON VARIABLES STORED IN THE MEMORY MANAGER, '// &
2314  'IN '//trim(cunits)
2315  !
2316  ! -- set up stage tableobj
2317  call table_cr(memtab, 'MEM SUM', title)
2318  call memtab%table_df(nrows, nterms, iout)
2319  !
2320  ! -- data type
2321  text = 'COMPONENT'
2322  call memtab%initialize_column(text, 20, alignment=tableft)
2323  !
2324  ! -- memory allocated for characters
2325  text = 'CHARACTER'
2326  call memtab%initialize_column(text, 15, alignment=tabcenter)
2327  !
2328  ! -- memory allocated for logical
2329  text = 'LOGICAL'
2330  call memtab%initialize_column(text, 15, alignment=tabcenter)
2331  !
2332  ! -- memory allocated for integers
2333  text = 'INTEGER'
2334  call memtab%initialize_column(text, 15, alignment=tabcenter)
2335  !
2336  ! -- memory allocated for reals
2337  text = 'REAL'
2338  call memtab%initialize_column(text, 15, alignment=tabcenter)
2339  !
2340  ! -- total memory allocated
2341  text = 'TOTAL'
2342  call memtab%initialize_column(text, 15, alignment=tabcenter)
2343  end subroutine mem_summary_table
2344 
2345  !> @brief Create a table if memory_print_option is 'ALL'
2346  !<
2347  subroutine mem_detailed_table(iout, nrows)
2348  integer(I4B), intent(in) :: iout !< unit number for mfsim.lst
2349  integer(I4B), intent(in) :: nrows !< number of table rows
2350  ! -- local
2351  character(len=LINELENGTH) :: title
2352  character(len=LINELENGTH) :: text
2353  integer(I4B) :: nterms
2354  ! -- formats
2355  ! -- code
2356  nterms = 5
2357  !
2358  ! -- set up table title
2359  title = 'DETAILED INFORMATION ON VARIABLES STORED IN THE MEMORY MANAGER'
2360  !
2361  ! -- set up stage tableobj
2362  call table_cr(memtab, 'MEM DET', title)
2363  call memtab%table_df(nrows, nterms, iout)
2364  !
2365  ! -- origin
2366  text = 'ORIGIN'
2367  call memtab%initialize_column(text, lenmempath, alignment=tableft)
2368  !
2369  ! -- variable
2370  text = 'VARIABLE NAME'
2371  call memtab%initialize_column(text, lenvarname, alignment=tableft)
2372  !
2373  ! -- data type
2374  text = 'DATA TYPE'
2375  call memtab%initialize_column(text, 16, alignment=tableft)
2376  !
2377  ! -- size
2378  text = 'NUMBER OF ITEMS'
2379  call memtab%initialize_column(text, 20, alignment=tabright)
2380  !
2381  ! -- is it a pointer
2382  text = 'ASSOCIATED VARIABLE'
2383  call memtab%initialize_column(text, lenmemaddress, alignment=tableft)
2384  end subroutine mem_detailed_table
2385 
2386  !> @brief Write a row for the memory_print_option 'SUMMARY' table
2387  !<
2388  subroutine mem_summary_line(component, rchars, rlog, rint, rreal, bytes)
2389  character(len=*), intent(in) :: component !< character defining the program component (e.g. solution)
2390  real(DP), intent(in) :: rchars !< allocated size of characters (in common units)
2391  real(DP), intent(in) :: rlog !< allocated size of logical (in common units)
2392  real(DP), intent(in) :: rint !< allocated size of integer variables (in common units)
2393  real(DP), intent(in) :: rreal !< allocated size of real variables (in common units)
2394  real(DP), intent(in) :: bytes !< total allocated memory in memory manager (in common units)
2395  ! -- formats
2396  ! -- code
2397  !
2398  ! -- write line
2399  call memtab%add_term(component)
2400  call memtab%add_term(rchars)
2401  call memtab%add_term(rlog)
2402  call memtab%add_term(rint)
2403  call memtab%add_term(rreal)
2404  call memtab%add_term(bytes)
2405  end subroutine mem_summary_line
2406 
2407  !> @brief Determine appropriate memory unit and conversion factor
2408  !<
2409  subroutine mem_units(bytes, fact, cunits)
2410  ! -- dummy
2411  real(DP), intent(in) :: bytes !< total nr. of bytes
2412  real(DP), intent(inout) :: fact !< conversion factor
2413  character(len=*), intent(inout) :: cunits !< string with memory unit
2414  ! -- local
2415  ! -- formats
2416  ! -- code
2417  !
2418  ! -- initialize factor and unit string
2419  cunits = 'UNKNOWN'
2420  fact = done
2421  !
2422  ! -- set factor
2423  if (bytes < dep3) then
2424  fact = done
2425  cunits = 'BYTES'
2426  else if (bytes < dep6) then
2427  fact = dem3
2428  cunits = 'KILOBYTES'
2429  else if (bytes < dep9) then
2430  fact = dem6
2431  cunits = 'MEGABYTES'
2432  else
2433  fact = dem9
2434  cunits = 'GIGABYTES'
2435  end if
2436  end subroutine mem_units
2437 
2438  !> @brief Create and fill a table with the total allocated memory
2439  !< in the memory manager
2440  subroutine mem_summary_total(iout, bytes)
2441  integer(I4B), intent(in) :: iout !< unit number for mfsim.lst
2442  real(DP), intent(in) :: bytes !< total number of bytes allocated in the memory manager
2443  ! -- local
2444  character(len=LINELENGTH) :: title
2445  character(len=LINELENGTH) :: text
2446  character(LEN=10) :: cunits
2447  integer(I4B) :: nterms
2448  integer(I4B) :: nrows
2449  real(DP) :: fact
2450  real(DP) :: smb
2451  ! -- formats
2452  ! -- code
2453  !
2454  ! -- calculate factor and memory units
2455  call mem_units(bytes, fact, cunits)
2456  !
2457  ! -- set table terms
2458  nterms = 2
2459  nrows = 6
2460  !
2461  ! -- set up table title
2462  title = 'MEMORY MANAGER TOTAL STORAGE BY DATA TYPE, IN '//trim(cunits)
2463  !
2464  ! -- set up stage tableobj
2465  call table_cr(memtab, 'MEM TOT', title)
2466  call memtab%table_df(nrows, nterms, iout)
2467  !
2468  ! -- data type
2469  text = 'DATA TYPE'
2470  call memtab%initialize_column(text, 15, alignment=tableft)
2471  !
2472  ! -- number of values
2473  text = 'ALLOCATED MEMORY'
2474  call memtab%initialize_column(text, 15, alignment=tabcenter)
2475  !
2476  ! -- write data
2477  !
2478  ! -- characters
2479  smb = real(nvalues_astr, dp) * fact
2480  call memtab%add_term('Character')
2481  call memtab%add_term(smb)
2482  !
2483  ! -- logicals
2484  smb = real(nvalues_alogical * lgp, dp) * fact
2485  call memtab%add_term('Logical')
2486  call memtab%add_term(smb)
2487  !
2488  ! -- integers
2489  smb = real(nvalues_aint * i4b, dp) * fact
2490  call memtab%add_term('Integer')
2491  call memtab%add_term(smb)
2492  !
2493  ! -- reals
2494  smb = real(nvalues_adbl * dp, dp) * fact
2495  call memtab%add_term('Real')
2496  call memtab%add_term(smb)
2497  !
2498  ! -- total memory usage
2499  call memtab%print_separator()
2500  smb = bytes * fact
2501  call memtab%add_term('Total')
2502  call memtab%add_term(smb)
2503  !
2504  ! -- Virtual memory
2505  smb = calc_virtual_mem() * fact
2506  call memtab%add_term('Virtual')
2507  call memtab%add_term(smb)
2508  !
2509  ! -- deallocate table
2510  call mem_cleanup_table()
2511  end subroutine mem_summary_total
2512 
2513  !> @brief Generic function to clean a memory manager table
2514  !<
2515  subroutine mem_cleanup_table()
2516  ! -- local
2517  ! -- formats
2518  ! -- code
2519  call memtab%table_da()
2520  deallocate (memtab)
2521  nullify (memtab)
2522  end subroutine mem_cleanup_table
2523 
2524  !> @brief Write memory manager memory usage based on the
2525  !! user-specified memory_print_option
2526  !!
2527  !! The total memory usage by data types (int, real, etc.)
2528  !! is written for every simulation.
2529  !<
2530  subroutine mem_write_usage(iout)
2531  integer(I4B), intent(in) :: iout !< unit number for mfsim.lst
2532  ! -- local
2533  class(memorytype), pointer :: mt
2534  character(len=LENMEMADDRESS), allocatable, dimension(:) :: cunique
2535  ! character(len=LENMEMPATH) :: mem_path
2536  character(len=LENMEMPATH) :: context
2537  character(len=LENCOMPONENTNAME) :: component
2538  character(len=LENCOMPONENTNAME) :: subcomponent
2539  character(len=LENMEMADDRESS) :: context_component
2540  character(LEN=10) :: cunits
2541  type(memorycontaineriteratortype), allocatable :: itr
2542  integer(I4B) :: icomp
2543  integer(I4B) :: ilen
2544  integer(I8B) :: nchars
2545  integer(I8B) :: nlog
2546  integer(I8B) :: nint
2547  integer(I8B) :: nreal
2548  real(dp) :: simbytes
2549  real(dp) :: fact
2550  real(dp) :: rchars
2551  real(dp) :: rlog
2552  real(dp) :: rint
2553  real(dp) :: rreal
2554  real(dp) :: bytes
2555  ! -- formats
2556  ! -- code
2557  !
2558  ! -- Calculate simulation memory allocation
2559  simbytes = (nvalues_astr + &
2560  nvalues_alogical * lgp + &
2561  nvalues_aint * i4b + &
2562  nvalues_adbl * dp)
2563  simbytes = real(simbytes, dp)
2564  !
2565  ! -- calculate factor and memory units
2566  call mem_units(simbytes, fact, cunits)
2567  !
2568  ! -- Write summary table for simulation components
2569  if (iprmem == 1) then
2570  !
2571  ! -- Find unique names of simulation components
2572  call mem_unique_origins(cunique)
2573  call mem_summary_table(iout, size(cunique), cunits)
2574  do icomp = 1, size(cunique)
2575  nchars = 0
2576  nlog = 0
2577  nint = 0
2578  nreal = 0
2579  bytes = dzero
2580  ilen = len_trim(cunique(icomp))
2581  itr = memorystore%iterator()
2582  do while (itr%has_next())
2583  call itr%next()
2584  mt => itr%value()
2585  call split_mem_path(mt%path, component, subcomponent)
2586  context = get_mem_path_context(mt%path)
2587  context_component = trim(context)//component
2588  if (cunique(icomp) /= context_component(1:ilen)) cycle
2589  if (.not. mt%master) cycle
2590  if (mt%memtype(1:6) == 'STRING') then
2591  nchars = nchars + mt%isize * mt%element_size
2592  else if (mt%memtype(1:7) == 'LOGICAL') then
2593  nlog = nlog + mt%isize
2594  else if (mt%memtype(1:7) == 'INTEGER') then
2595  nint = nint + mt%isize
2596  else if (mt%memtype(1:6) == 'DOUBLE') then
2597  nreal = nreal + mt%isize
2598  end if
2599  end do
2600  !
2601  ! -- calculate size of each data type in bytes
2602  rchars = real(nchars, dp) * fact
2603  rlog = real(nlog * lgp, dp) * fact
2604  rint = real(nint * i4b, dp) * fact
2605  rreal = real(nreal * dp, dp) * fact
2606  !
2607  ! -- calculate total storage in bytes
2608  bytes = rchars + rlog + rint + rreal
2609  !
2610  ! -- write data
2611  call mem_summary_line(cunique(icomp), rchars, rlog, rint, rreal, bytes)
2612  end do
2613  call mem_cleanup_table()
2614  end if
2615  !
2616  ! -- Write table with all variables for iprmem == 2
2617  if (iprmem == 2) then
2618  call mem_print_detailed(iout)
2619  end if
2620  !
2621  ! -- Write total memory allocation
2622  call mem_summary_total(iout, simbytes)
2623  end subroutine mem_write_usage
2624 
2625  subroutine mem_print_detailed(iout)
2626  integer(I4B) :: iout
2627  ! local
2628  class(memorytype), pointer :: mt
2629  type(memorycontaineriteratortype), allocatable :: itr
2630 
2631  call mem_detailed_table(iout, memorystore%count())
2632  itr = memorystore%iterator()
2633  do while (itr%has_next())
2634  call itr%next()
2635  mt => itr%value()
2636  call mt%table_entry(memtab)
2637  end do
2638  call mem_cleanup_table()
2639 
2640  end subroutine mem_print_detailed
2641 
2642  !> @brief Sum up virtual memory, i.e. memory
2643  !< that is owned by other processes
2644  function calc_virtual_mem() result(vmem_size)
2645  real(dp) :: vmem_size
2646  ! local
2647  type(memorycontaineriteratortype), allocatable :: itr
2648  type(memorytype), pointer :: mt
2649 
2650  vmem_size = dzero
2651  itr = memorystore%iterator()
2652  do while (itr%has_next())
2653  call itr%next()
2654  mt => itr%value()
2655  if (index(mt%path, "__P") == 1) then
2656  vmem_size = mt%element_size * mt%isize + vmem_size
2657  end if
2658  end do
2659 
2660  end function calc_virtual_mem
2661 
2662  !> @brief Release a memory store entry: deallocate data and update counters
2663  !!
2664  !! Deallocates the data held by mt, zeroes mt%isize, and decrements the
2665  !! appropriate nvalues_* counter for master entries. no-op when data has
2666  !! already been released. Primarily intended to support the release of
2667  !! input context memory prior to simulation runtime.
2668  !<
2669  subroutine mem_release(mt)
2670  type(memorytype), pointer, intent(inout) :: mt
2671 
2672  if (.not. mt%mt_associated()) return
2673 
2674  if (mt%master) then
2675  if (mt%memtype(1:6) == 'STRING') then
2676  ! nvalues_astr increments differ: scalar adds element_size (ilen),
2677  ! arrays (str1d, charstr1d) add isize only. For IDM release the
2678  ! variables are arrays, so decrement by isize to match.
2679  if (mt%isize == 1) then
2680  nvalues_astr = nvalues_astr - mt%element_size
2681  else
2682  nvalues_astr = nvalues_astr - mt%isize
2683  end if
2684  else if (mt%memtype(1:7) == 'LOGICAL') then
2685  nvalues_alogical = nvalues_alogical - mt%isize
2686  else if (mt%memtype(1:7) == 'INTEGER') then
2687  nvalues_aint = nvalues_aint - mt%isize
2688  else if (mt%memtype(1:6) == 'DOUBLE') then
2689  nvalues_adbl = nvalues_adbl - mt%isize
2690  end if
2691  end if
2692 
2693  call mt%mt_deallocate()
2694  mt%isize = 0
2695  end subroutine mem_release
2696 
2697  !> @brief Deallocate memory in the memory manager
2698  !<
2699  subroutine mem_da()
2700  ! -- modules
2701  use versionmodule, only: idevelopmode
2702  ! -- local
2703  class(memorytype), pointer :: mt
2704  type(memorycontaineriteratortype), allocatable :: itr
2705  ! -- code
2706  itr = memorystore%iterator()
2707  do while (itr%has_next())
2708  call itr%next()
2709  mt => itr%value()
2710  call mt%mt_deallocate()
2711  if (idevelopmode == 1) call mem_da_check(mt)
2712  deallocate (mt)
2713  end do
2714 
2715  call memorystore%clear()
2716  if (count_errors() > 0) then
2717  call store_error('Could not clear memory list.', terminate=.true.)
2718  end if
2719  end subroutine mem_da
2720 
2721  subroutine mem_da_check(mt)
2722  ! -- modules
2723  use inputoutputmodule, only: upcase
2724  ! -- dummy
2725  class(memorytype), pointer :: mt
2726  ! -- local
2727  character(len=LINELENGTH) :: error_msg
2728  character(len=LENVARNAME) :: ucname
2729  !
2730  ! -- check if memory has been deallocated
2731  if (mt%mt_associated() .and. mt%element_size == -1) then
2732  error_msg = trim(adjustl(mt%path))//' '// &
2733  trim(adjustl(mt%name))//' has invalid element size'
2734  call store_error(trim(error_msg))
2735  end if
2736  !
2737  ! -- check if memory has been deallocated
2738  if (mt%mt_associated() .and. mt%isize > 0) then
2739  error_msg = trim(adjustl(mt%path))//' '// &
2740  trim(adjustl(mt%name))//' not deallocated'
2741  call store_error(trim(error_msg))
2742  end if
2743  !
2744  ! -- check case of varname
2745  ucname = mt%name
2746  call upcase(ucname)
2747  if (mt%name /= ucname) then
2748  error_msg = trim(adjustl(mt%path))//' '// &
2749  trim(adjustl(mt%name))//' not upper case'
2750  call store_error(trim(error_msg))
2751  end if
2752  end subroutine mem_da_check
2753 
2754  !> @brief Create a array with unique first components from all memory paths.
2755  !! Only the first component of the memory path is evaluated.
2756  !<
2757  subroutine mem_unique_origins(cunique)
2758  ! -- modules
2760  ! -- dummy
2761  character(len=LENMEMADDRESS), allocatable, dimension(:), intent(inout) :: &
2762  cunique !< array with unique first components
2763  ! -- local
2764  class(memorytype), pointer :: mt
2765  character(len=LENMEMPATH) :: context
2766  character(len=LENCOMPONENTNAME) :: component
2767  character(len=LENCOMPONENTNAME) :: subcomponent
2768  character(len=LENMEMADDRESS) :: context_component
2769  type(memorycontaineriteratortype), allocatable :: itr
2770  integer(I4B) :: ipa
2771  ! -- code
2772  !
2773  ! -- initialize cunique
2774  allocate (cunique(0))
2775  !
2776  ! -- find unique origins
2777  itr = memorystore%iterator()
2778  do while (itr%has_next())
2779  call itr%next()
2780  mt => itr%value()
2781  call split_mem_path(mt%path, component, subcomponent)
2782  context = get_mem_path_context(mt%path)
2783  context_component = trim(context)//component
2784  ipa = ifind(cunique, context_component)
2785  if (ipa < 1) then
2786  call expandarray(cunique, 1)
2787  cunique(size(cunique)) = context_component
2788  end if
2789  end do
2790  end subroutine mem_unique_origins
2791 
2792 end module memorymanagermodule
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 lencomponentname
maximum length of a component name
Definition: Constants.f90:18
@ tabcenter
centered table column
Definition: Constants.f90:173
@ tabright
right justified table column
Definition: Constants.f90:174
@ tableft
left justified table column
Definition: Constants.f90:172
integer(i4b), parameter lenmemaddress
maximum length of the full memory address, including variable name
Definition: Constants.f90:31
real(dp), parameter dep3
real constant 1000
Definition: Constants.f90:88
@ tabucstring
upper case string table data
Definition: Constants.f90:181
@ tabstring
string table data
Definition: Constants.f90:180
@ tabreal
real table data
Definition: Constants.f90:183
@ tabinteger
integer table data
Definition: Constants.f90:182
real(dp), parameter dep6
real constant 1000000
Definition: Constants.f90:89
integer(i4b), parameter lenmemseparator
maximum length of the memory path separator used, currently a '/'
Definition: Constants.f90:26
real(dp), parameter dep9
real constant 1e9
Definition: Constants.f90:90
integer(i4b), parameter lenvarname
maximum length of a variable name
Definition: Constants.f90:17
integer(i4b), parameter, public lenmemtype
maximum length of a memory manager type
Definition: Constants.f90:62
real(dp), parameter dem3
real constant 1e-3
Definition: Constants.f90:106
real(dp), parameter dem6
real constant 1e-6
Definition: Constants.f90:109
real(dp), parameter dzero
real constant zero
Definition: Constants.f90:65
real(dp), parameter dem9
real constant 1e-9
Definition: Constants.f90:112
integer(i4b), parameter lenmempath
maximum length of the memory path
Definition: Constants.f90:27
real(dp), parameter done
real constant 1
Definition: Constants.f90:76
subroutine, public upcase(word)
Convert to upper case.
This module defines variable data types.
Definition: kind.f90:8
character(len=lenmempath) function get_mem_path_context(mem_path)
Return the context from the memory path.
subroutine mem_check_length(name, max_length, description)
Generic routine to check the length of (parts of) the memory address.
subroutine strip_context_mem_path(mem_path, mem_path_no_context)
Remove the context from the memory path.
subroutine split_mem_path(mem_path, component, subcomponent)
Split the memory path into component(s)
subroutine reallocate_int2d(aint, ncol, nrow, name, mem_path)
Reallocate a 2-dimensional integer array.
subroutine allocate_logical(sclr, name, mem_path)
Allocate a logical scalar.
subroutine allocate_int2d(aint, ncol, nrow, name, mem_path)
Allocate a 2-dimensional integer array.
subroutine mem_summary_line(component, rchars, rlog, rint, rreal, bytes)
Write a row for the memory_print_option 'SUMMARY' table.
subroutine allocate_dbl3d(adbl, ncol, nrow, nlay, name, mem_path)
Allocate a 3-dimensional real array.
integer(i8b) nvalues_adbl
subroutine deallocate_str1d(astr1d, name, mem_path)
Deallocate an array of defined-length character strings.
subroutine deallocate_int(sclr)
DEPRECATED. The memory manager will handle the deallocation of the pointer.
subroutine deallocate_logical1d(alog, name, mem_path)
DEPRECATED. The memory manager will handle the deallocation of the pointer.
type(tabletype), pointer memtab
subroutine setptr_int3d(aint, name, mem_path)
Set pointer to 3d integer array.
subroutine mem_detailed_table(iout, nrows)
Create a table if memory_print_option is 'ALL'.
subroutine deallocate_charstr1d(astr1d, name, mem_path)
DEPRECATED. The memory manager will handle the deallocation of the pointer.
subroutine allocate_charstr1d(acharstr1d, ilen, nrow, name, mem_path)
Allocate a 1-dimensional array of deferred-length CharacterStringType.
subroutine reallocate_charstr1d(acharstr1d, ilen, nrow, name, mem_path)
Reallocate a 1-dimensional deferred length string array.
subroutine, public mem_write_usage(iout)
Write memory manager memory usage based on the user-specified memory_print_option.
subroutine reallocate_dbl2d(adbl, ncol, nrow, name, mem_path)
Reallocate a 2-dimensional real array.
integer(i8b) nvalues_aint
subroutine setptr_int(sclr, name, mem_path)
Set pointer to integer scalar.
subroutine checkin_charstr1d(acharstr1d, ilen, name, mem_path, name2, mem_path2)
Check in an existing 1d CharacterStringType array with a new address (name + path)
subroutine mem_cleanup_table()
Generic function to clean a memory manager table.
subroutine copyptr_int1d(aint, name, mem_path, mem_path_copy)
Make a copy of a 1-dimensional integer array.
subroutine deallocate_dbl1d(adbl, name, mem_path)
DEPRECATED. The memory manager will handle the deallocation of the pointer.
subroutine allocate_str1d(astr1d, ilen, nrow, name, mem_path)
Allocate a 1-dimensional defined length string array.
subroutine allocate_str(sclr, ilen, name, mem_path)
Allocate a character string.
subroutine, public get_mem_type(name, mem_path, var_type)
@ brief Get the variable memory type
subroutine setptr_int2d(aint, name, mem_path)
Set pointer to 2d integer array.
subroutine, public mem_da()
Deallocate memory in the memory manager.
subroutine deallocate_int1d(aint, name, mem_path)
DEPRECATED. The memory manager will handle the deallocation of the pointer.
integer(i8b) nvalues_astr
subroutine deallocate_dbl(sclr)
DEPRECATED. The memory manager will handle the deallocation of the pointer.
subroutine copyptr_int2d(aint, name, mem_path, mem_path_copy)
Make a copy of a 2-dimensional integer array.
subroutine mem_da_check(mt)
subroutine allocate_dbl(sclr, name, mem_path)
Allocate a real scalar.
real(dp) function calc_virtual_mem()
Sum up virtual memory, i.e. memory.
subroutine copyptr_dbl2d(adbl, name, mem_path, mem_path_copy)
Make a copy of a 2-dimensional real array.
subroutine reassignptr_int2d(aint, name, mem_path, name_target, mem_path_target)
Set the pointer for a 2-dimensional integer array to.
subroutine reallocate_logical1d(alog, nrow, name, mem_path)
Reallocate a 1-dimensional logical array.
subroutine setptr_dbl(sclr, name, mem_path)
Set pointer to a real scalar.
subroutine deallocate_int3d(aint, name, mem_path)
DEPRECATED. The memory manager will handle the deallocation of the pointer.
subroutine deallocate_int2d(aint, name, mem_path)
DEPRECATED. The memory manager will handle the deallocation of the pointer.
subroutine reassignptr_dbl1d(adbl, name, mem_path, name_target, mem_path_target)
Set the pointer for a 1-dimensional real array to.
subroutine, public mem_release(mt)
Release a memory store entry: deallocate data and update counters.
subroutine allocate_int3d(aint, ncol, nrow, nlay, name, mem_path)
Allocate a 3-dimensional integer array.
subroutine, public get_mem_shape(name, mem_path, mem_shape)
@ brief Get the variable memory shape
subroutine deallocate_dbl2d(adbl, name, mem_path)
DEPRECATED. The memory manager will handle the deallocation of the pointer.
subroutine mem_units(bytes, fact, cunits)
Determine appropriate memory unit and conversion factor.
subroutine setptr_int1d(aint, name, mem_path)
Set pointer to 1d integer array.
subroutine setptr_str1d(astr1d, name, mem_path)
Set pointer to a fixed-length string array.
subroutine checkin_int2d(aint2d, name, mem_path, name2, mem_path2)
Check in an existing 2d integer array with a new address (name + path)
type(memorystoretype), public memorystore
subroutine reallocate_dbl1d(adbl, nrow, name, mem_path)
Reallocate a 1-dimensional real array.
subroutine setptr_dbl2d(adbl, name, mem_path)
Set pointer to a 2d real array.
subroutine deallocate_logical(sclr)
DEPRECATED. The memory manager will handle the deallocation of the pointer.
subroutine setptr_logical1d(alog, name, mem_path)
Set pointer to 1d logical array.
subroutine checkin_dbl2d(adbl2d, name, mem_path, name2, mem_path2)
Check in an existing 2d double precision array with a new address (name + path)
subroutine deallocate_dbl3d(adbl, name, mem_path)
DEPRECATED. The memory manager will handle the deallocation of the pointer.
subroutine reallocate_int1d(aint, nrow, name, mem_path)
Reallocate a 1-dimensional integer array.
subroutine checkin_logical1d(alog, name, mem_path, name2, mem_path2)
Check in an existing 1d logical array with a new address (name + path)
subroutine, public get_from_memorystore(name, mem_path, mt, found, check)
@ brief Get a memory type entry from the memory list
subroutine, public mem_print_detailed(iout)
subroutine reallocate_str1d(astr, ilen, nrow, name, mem_path)
Reallocate a 1-dimensional defined length string array.
subroutine copyptr_dbl1d(adbl, name, mem_path, mem_path_copy)
Make a copy of a 1-dimensional real array.
subroutine allocate_logical1d(alog, nrow, name, mem_path)
Allocate a 1-dimensional logical array.
subroutine reassignptr_dbl2d(adbl, name, mem_path, name_target, mem_path_target)
Set the pointer for a 2-dimensional real array to.
subroutine copyptr_logical1d(alog, name, mem_path, mem_path_copy)
Make a copy of a 1-dimensional logical array.
subroutine allocate_int1d(aint, nrow, name, mem_path)
Allocate a 1-dimensional integer array.
subroutine allocate_int(sclr, name, mem_path)
Allocate a integer scalar.
subroutine reassignptr_int1d(aint, name, mem_path, name_target, mem_path_target)
Set the pointer for a 1-dimensional integer array to.
subroutine mem_summary_total(iout, bytes)
Create and fill a table with the total allocated memory.
subroutine, public get_isize(name, mem_path, isize)
@ brief Get the number of elements for this variable
subroutine allocate_dbl2d(adbl, ncol, nrow, name, mem_path)
Allocate a 2-dimensional real array.
subroutine deallocate_str(sclr, name, mem_path)
DEPRECATED. The memory manager will handle the deallocation of the pointer.
subroutine, public get_mem_rank(name, mem_path, rank)
@ brief Get the variable rank
subroutine checkin_dbl1d(adbl, name, mem_path, name2, mem_path2)
Check in an existing 1d double precision array with a new address (name + path)
subroutine checkin_int1d(aint, name, mem_path, name2, mem_path2)
Check in an existing 1d integer array with a new address (name + path)
subroutine reassignptr_logical1d(alog, name, mem_path, name_target, mem_path_target)
Set the pointer for a 1-dimensional logical array to.
subroutine reassignptr_int(sclr, name, mem_path, name_target, mem_path_target)
Set the pointer for an integer scalar to.
subroutine, public copy_dbl1d(adbl, name, mem_path)
Copy values from a 1-dimensional real array in the memory.
subroutine setptr_dbl3d(adbl, name, mem_path)
Set pointer to a 3d real array.
subroutine, public get_mem_elem_size(name, mem_path, size)
@ brief Get the memory size of a single element of the stored variable
subroutine setptr_dbl1d(adbl, name, mem_path)
Set pointer to a 1d real array.
subroutine setptr_str(asrt, name, mem_path)
Set pointer to a string (scalar)
integer(i8b) nvalues_alogical
subroutine setptr_charstr1d(acharstr1d, name, mem_path)
Set pointer to an array of CharacterStringType.
subroutine mem_unique_origins(cunique)
Create a array with unique first components from all memory paths. Only the first component of the me...
subroutine mem_summary_table(iout, nrows, cunits)
Create a table if memory_print_option is 'SUMMARY'.
subroutine setptr_logical(sclr, name, mem_path)
Set pointer to a logical scalar.
subroutine, public mem_set_print_option(iout, keyword, error_msg)
Set the memory print option.
subroutine allocate_dbl1d(adbl, nrow, name, mem_path)
Allocate a 1-dimensional real array.
subroutine allocate_error(varname, mem_path, istat, isize)
Issue allocation error message and stop program execution.
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
This module contains simulation variables.
Definition: SimVariables.f90:9
character(len=maxcharlen) errmsg
error message string
subroutine, public table_cr(this, name, title)
Definition: Table.f90:87
This module contains version information.
Definition: version.f90:7
integer(i4b), parameter idevelopmode
Definition: version.f90:19
This class is used to store a single deferred-length character string. It was designed to work in an ...
Definition: CharString.f90:23
An iterator used to iterate through a MemoryContainer.