MODFLOW 6  version 6.7.0.dev3
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 (LOGICAL or 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  logical(LGP), dimension(:), pointer, contiguous :: alogical1d => null() !< pointer to 1d logical array
37  integer(I4B), dimension(:), pointer, contiguous :: aint1d => null() !< pointer to 1d integer array
38  integer(I4B), dimension(:, :), pointer, contiguous :: aint2d => null() !< pointer to 2d integer array
39  integer(I4B), dimension(:, :, :), pointer, contiguous :: aint3d => null() !< pointer to 3d integer array
40  real(dp), dimension(:), pointer, contiguous :: adbl1d => null() !< pointer to 1d double array
41  real(dp), dimension(:, :), pointer, contiguous :: adbl2d => null() !< pointer to 2d double array
42  real(dp), dimension(:, :, :), pointer, contiguous :: adbl3d => null() !< pointer to 3d double array
43  type(characterstringtype), dimension(:), pointer, contiguous :: &
44  acharstr1d => null() !< pointer to the 1d character string array
45  contains
46  procedure :: table_entry
47  procedure :: mt_associated
48  procedure :: mt_deallocate
49  end type
50 
51 contains
52 
53  subroutine table_entry(this, memtab)
54  ! -- dummy
55  class(memorytype) :: this
56  type(tabletype), intent(inout) :: memtab
57  ! -- local
58  character(len=16) :: cmem
59  character(len=LENMEMADDRESS) :: cptr
60  integer(I4B) :: ipos
61  ! -- formats
62  !
63  ! -- determine memory type
64  ipos = index(this%memtype, ' (')
65  if (ipos < 1) then
66  ipos = 16
67  else
68  ipos = min(16, ipos - 1)
69  end if
70  cmem = this%memtype(1:ipos)
71  !
72  ! -- Set pointer string
73  cptr = '--'
74  if (.not. this%master) then
75  cptr = create_mem_address(this%masterPath, this%mastername)
76  end if
77  !
78  ! -- write data to the table
79  call memtab%add_term(this%path)
80  call memtab%add_term(this%name)
81  call memtab%add_term(cmem)
82  call memtab%add_term(this%isize)
83  call memtab%add_term(cptr)
84  end subroutine table_entry
85 
86  function mt_associated(this) result(al)
87  class(memorytype) :: this
88  logical :: al
89  al = .false.
90  if (associated(this%strsclr)) al = .true.
91  if (associated(this%logicalsclr)) al = .true.
92  if (associated(this%intsclr)) al = .true.
93  if (associated(this%dblsclr)) al = .true.
94  if (associated(this%alogical1d)) al = .true.
95  if (associated(this%astr1d)) al = .true.
96  if (associated(this%aint1d)) al = .true.
97  if (associated(this%aint2d)) al = .true.
98  if (associated(this%aint3d)) al = .true.
99  if (associated(this%adbl1d)) al = .true.
100  if (associated(this%adbl2d)) al = .true.
101  if (associated(this%adbl3d)) al = .true.
102  if (associated(this%acharstr1d)) al = .true.
103  end function mt_associated
104 
105  subroutine mt_deallocate(this)
106  use iso_c_binding, only: c_loc, c_ptr, c_null_ptr, c_f_pointer
107  class(memorytype) :: this
108  integer(I4B) :: n
109  type(c_ptr) :: cptr
110 
111  character(len=1), dimension(:), pointer :: astr1d
112 
113  if (associated(this%strsclr)) then
114  if (this%master) deallocate (this%strsclr)
115  nullify (this%strsclr)
116  end if
117 
118  if (associated(this%logicalsclr)) then
119  if (this%master) deallocate (this%logicalsclr)
120  nullify (this%logicalsclr)
121  end if
122 
123  if (associated(this%intsclr)) then
124  if (this%master) deallocate (this%intsclr)
125  nullify (this%intsclr)
126  end if
127 
128  if (associated(this%dblsclr)) then
129  if (this%master) deallocate (this%dblsclr)
130  nullify (this%dblsclr)
131  end if
132 
133  ! 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.
134  ! Due to a bug in the gfortran compiler we can't use a deferred length character variable
135  ! https://gcc.gnu.org/bugzilla/show_bug.cgi?id=106317
136  !
137  ! 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
138  ! computed by the actual length of the string multiplied by the array size.
139  ! So we go from the actual character(len=element_size), dimension(isize) to a character(len=1), dimension(isize*element_size).
140 
141  if (associated(this%astr1d)) then
142  select type (item => this%astr1d)
143  type is (character(*))
144  cptr = c_loc(item)
145  class default
146  cptr = c_null_ptr
147  end select
148 
149  call c_f_pointer(cptr, astr1d, [this%isize * this%element_size])
150 
151 #if __GFORTRAN__ && ((__GNUC__ < 13) || (__GNUC__ == 13 && __GNUC_MINOR__ < 3))
152  if (this%master) deallocate (astr1d)
153 #else
154  if (this%master) deallocate (this%astr1d)
155 #endif
156 
157  nullify (this%astr1d)
158  end if
159 
160  if (associated(this%alogical1d)) then
161  if (this%master) deallocate (this%alogical1d)
162  nullify (this%alogical1d)
163  end if
164 
165  if (associated(this%aint1d)) then
166  if (this%master) deallocate (this%aint1d)
167  nullify (this%aint1d)
168  end if
169 
170  if (associated(this%aint2d)) then
171  if (this%master) deallocate (this%aint2d)
172  nullify (this%aint2d)
173  end if
174 
175  if (associated(this%aint3d)) then
176  if (this%master) deallocate (this%aint3d)
177  nullify (this%aint3d)
178  end if
179 
180  if (associated(this%adbl1d)) then
181  if (this%master) deallocate (this%adbl1d)
182  nullify (this%adbl1d)
183  end if
184 
185  if (associated(this%adbl2d)) then
186  if (this%master) deallocate (this%adbl2d)
187  nullify (this%adbl2d)
188  end if
189 
190  if (associated(this%adbl3d)) then
191  if (this%master) deallocate (this%adbl3d)
192  nullify (this%adbl3d)
193  end if
194 
195  if (associated(this%acharstr1d)) then
196  if (this%master) then
197  do n = 1, size(this%acharstr1d)
198  call this%acharstr1d(n)%destroy()
199  end do
200  deallocate (this%acharstr1d)
201  end if
202  nullify (this%acharstr1d)
203  end if
204  end subroutine mt_deallocate
205 
206 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:106
subroutine table_entry(this, memtab)
Definition: Memory.F90:54
logical function mt_associated(this)
Definition: Memory.F90:87
This class is used to store a single deferred-length character string. It was designed to work in an ...
Definition: CharString.f90:23