MODFLOW 6  version 6.7.0.dev1
USGS Modular Hydrologic Model
Memory.F90
Go to the documentation of this file.
2 
3  use kindmodule, only: dp, lgp, i4b
9  use tablemodule, only: tabletype
11 
12  implicit none
13  private
14  public :: memorytype
15 
17  character(len=LENVARNAME) :: name !< name of the array
18  character(len=LENVARNAME) :: mastername = 'none' !< name of the master array
19  character(len=LENMEMPATH) :: path !< path to memory object
20  character(len=LENMEMPATH) :: masterpath = 'none' !< path to master memory object
21  character(len=LENMEMTYPE) :: memtype !< type (INTEGER or DOUBLE)
22  integer(I4B) :: id !< id, not used
23  integer(I4B) :: nrealloc = 0 !< number of times reallocated
24  integer(I4B) :: isize = -1 !< size of the array, equal to the number of array elements; 1 for scalars
25  integer(I4B) :: element_size = 0 !< byte size of an element; string length
26  integer(I4B) :: set_handler_idx = 0 !< index of side effect handler for external access
27  logical(LGP) :: master = .true. !< master copy, others point to this one
28  character(len=:), pointer :: strsclr => null() !< pointer to the character string
29  logical(LGP), pointer :: logicalsclr => null() !< pointer to the logical
30  integer(I4B), pointer :: intsclr => null() !< pointer to the integer
31  real(dp), pointer :: dblsclr => null() !< pointer to the double
32  ! The 1d character string array is handled differently than the other arrays due to a bug in gfortran 11.3 and 12.1.
33  ! Due to this bug the length of the string is not stored in the array descriptor. With a segmentation fault as a result
34  ! on deallocation.
35  class(*), dimension(:), pointer, contiguous :: astr1d => null() !< pointer to the 1d character string array
36  integer(I4B), dimension(:), pointer, contiguous :: aint1d => null() !< pointer to 1d integer array
37  integer(I4B), dimension(:, :), pointer, contiguous :: aint2d => null() !< pointer to 2d integer array
38  integer(I4B), dimension(:, :, :), pointer, contiguous :: aint3d => null() !< pointer to 3d integer array
39  real(dp), dimension(:), pointer, contiguous :: adbl1d => null() !< pointer to 1d double array
40  real(dp), dimension(:, :), pointer, contiguous :: adbl2d => null() !< pointer to 2d double array
41  real(dp), dimension(:, :, :), pointer, contiguous :: adbl3d => null() !< pointer to 3d double array
42  type(characterstringtype), dimension(:), pointer, contiguous :: &
43  acharstr1d => null() !< pointer to the 1d character string array
44  contains
45  procedure :: table_entry
46  procedure :: mt_associated
47  procedure :: mt_deallocate
48  end type
49 
50 contains
51 
52  subroutine table_entry(this, memtab)
53  ! -- dummy
54  class(memorytype) :: this
55  type(tabletype), intent(inout) :: memtab
56  ! -- local
57  character(len=16) :: cmem
58  character(len=LENMEMADDRESS) :: cptr
59  integer(I4B) :: ipos
60  ! -- formats
61  !
62  ! -- determine memory type
63  ipos = index(this%memtype, ' (')
64  if (ipos < 1) then
65  ipos = 16
66  else
67  ipos = min(16, ipos - 1)
68  end if
69  cmem = this%memtype(1:ipos)
70  !
71  ! -- Set pointer string
72  cptr = '--'
73  if (.not. this%master) then
74  cptr = create_mem_address(this%masterPath, this%mastername)
75  end if
76  !
77  ! -- write data to the table
78  call memtab%add_term(this%path)
79  call memtab%add_term(this%name)
80  call memtab%add_term(cmem)
81  call memtab%add_term(this%isize)
82  call memtab%add_term(cptr)
83  end subroutine table_entry
84 
85  function mt_associated(this) result(al)
86  class(memorytype) :: this
87  logical :: al
88  al = .false.
89  if (associated(this%strsclr)) al = .true.
90  if (associated(this%logicalsclr)) al = .true.
91  if (associated(this%intsclr)) al = .true.
92  if (associated(this%dblsclr)) al = .true.
93  if (associated(this%astr1d)) al = .true.
94  if (associated(this%aint1d)) al = .true.
95  if (associated(this%aint2d)) al = .true.
96  if (associated(this%aint3d)) al = .true.
97  if (associated(this%adbl1d)) al = .true.
98  if (associated(this%adbl2d)) al = .true.
99  if (associated(this%adbl3d)) al = .true.
100  if (associated(this%acharstr1d)) al = .true.
101  end function mt_associated
102 
103  subroutine mt_deallocate(this)
104  use iso_c_binding, only: c_loc, c_ptr, c_null_ptr, c_f_pointer
105  class(memorytype) :: this
106  integer(I4B) :: n
107  type(c_ptr) :: cptr
108 
109  character(len=1), dimension(:), pointer :: astr1d
110 
111  if (associated(this%strsclr)) then
112  if (this%master) deallocate (this%strsclr)
113  nullify (this%strsclr)
114  end if
115 
116  if (associated(this%logicalsclr)) then
117  if (this%master) deallocate (this%logicalsclr)
118  nullify (this%logicalsclr)
119  end if
120 
121  if (associated(this%intsclr)) then
122  if (this%master) deallocate (this%intsclr)
123  nullify (this%intsclr)
124  end if
125 
126  if (associated(this%dblsclr)) then
127  if (this%master) deallocate (this%dblsclr)
128  nullify (this%dblsclr)
129  end if
130 
131  ! Handle the dealloction of the 1d character string array differently due to a bug in gfortran 11.3, 12.1, 13.1 and 13.2.
132  ! Due to a bug in the gfortran compiler we can't use a deferred length character variable
133  ! https://gcc.gnu.org/bugzilla/show_bug.cgi?id=106317
134  !
135  ! We use a c_ptr to cast the pointer to a string array with a length of 1. The actual length of the array is
136  ! computed by the actual length of the string multiplied by the array size.
137  ! So we go from the actual character(len=element_size), dimension(isize) to a character(len=1), dimension(isize*element_size).
138 
139  if (associated(this%astr1d)) then
140  select type (item => this%astr1d)
141  type is (character(*))
142  cptr = c_loc(item)
143  class default
144  cptr = c_null_ptr
145  end select
146 
147  call c_f_pointer(cptr, astr1d, [this%isize * this%element_size])
148 
149 #if __GFORTRAN__ && ((__GNUC__ < 13) || (__GNUC__ == 13 && __GNUC_MINOR__ < 3))
150  if (this%master) deallocate (astr1d)
151 #else
152  if (this%master) deallocate (this%astr1d)
153 #endif
154 
155  nullify (this%astr1d)
156  end if
157 
158  if (associated(this%aint1d)) then
159  if (this%master) deallocate (this%aint1d)
160  nullify (this%aint1d)
161  end if
162 
163  if (associated(this%aint2d)) then
164  if (this%master) deallocate (this%aint2d)
165  nullify (this%aint2d)
166  end if
167 
168  if (associated(this%aint3d)) then
169  if (this%master) deallocate (this%aint3d)
170  nullify (this%aint3d)
171  end if
172 
173  if (associated(this%adbl1d)) then
174  if (this%master) deallocate (this%adbl1d)
175  nullify (this%adbl1d)
176  end if
177 
178  if (associated(this%adbl2d)) then
179  if (this%master) deallocate (this%adbl2d)
180  nullify (this%adbl2d)
181  end if
182 
183  if (associated(this%adbl3d)) then
184  if (this%master) deallocate (this%adbl3d)
185  nullify (this%adbl3d)
186  end if
187 
188  if (associated(this%acharstr1d)) then
189  if (this%master) then
190  do n = 1, size(this%acharstr1d)
191  call this%acharstr1d(n)%destroy()
192  end do
193  deallocate (this%acharstr1d)
194  end if
195  nullify (this%acharstr1d)
196  end if
197  end subroutine mt_deallocate
198 
199 end module memorytypemodule
This module contains simulation constants.
Definition: Constants.f90:9
@ tabcenter
centered table column
Definition: Constants.f90:172
@ tabright
right justified table column
Definition: Constants.f90:173
@ tableft
left justified table column
Definition: Constants.f90:171
integer(i4b), parameter lenmemaddress
maximum length of the full memory address, including variable name
Definition: Constants.f90:31
@ tabstring
string table data
Definition: Constants.f90:179
@ tabinteger
integer table data
Definition: Constants.f90:181
integer(i4b), parameter lentimeseriesname
maximum length of a time series name
Definition: Constants.f90:42
integer(i4b), parameter lenvarname
maximum length of a variable name
Definition: Constants.f90:17
integer(i4b), parameter, public maxmemrank
maximum memory manager length (up to 3-dimensional arrays)
Definition: Constants.f90:61
integer(i4b), parameter, public lenmemtype
maximum length of a memory manager type
Definition: Constants.f90:62
integer(i4b), parameter lenmempath
maximum length of the memory path
Definition: Constants.f90:27
This module defines variable data types.
Definition: kind.f90:8
character(len=lenmemaddress) function create_mem_address(mem_path, var_name)
returns the address string of the memory object
subroutine mt_deallocate(this)
Definition: Memory.F90:104
subroutine table_entry(this, memtab)
Definition: Memory.F90:53
logical function mt_associated(this)
Definition: Memory.F90:86
This class is used to store a single deferred-length character string. It was designed to work in an ...
Definition: CharString.f90:23