The Elk Code
modramdisk.f90
Go to the documentation of this file.
1 
2 ! Copyright (C) 2021 J. K. Dewhurst, S. Sharma and E. K. U. Gross.
3 ! This file is distributed under the terms of the GNU General Public License.
4 ! See the file COPYING for license details.
5 
6 module modramdisk
7 
8 ! ramdisk is .true. if the RAM disk should be used
9 logical ramdisk
10 ! maximum allowed number of files on the RAM disk
11 integer, parameter, private :: maxfiles=32
12 ! maximum number of records per file
13 integer, parameter, private :: maxrec=32768
14 ! wrtdisk is .true. if files should also be written to disk
16 
17 ! record data stored as 4-byte words
18 type, private :: rec_t
19  integer(4), allocatable :: dat(:)
20 end type
21 
22 ! RAM disk file consisting of the filename and an array of records
23 type, private :: file_t
24  character(:), allocatable :: fname
25  type(rec_t), allocatable :: rec(:)
26 end type
27 
28 ! arrays of files constituting the RAM disk
29 type(file_t), allocatable, private :: file(:)
30 
31 ! private subroutines
32 private findfile,openfile
33 
34 contains
35 
36 subroutine initrd
37 ! this subroutine should not be called from a parallel region
38 implicit none
39 ! local variables
40 integer i
41 ! check if the RAM disk is already initialised
42 if (allocated(file)) return
43 ! allocate the files array and null the file names
44 allocate(file(maxfiles))
45 do i=1,maxfiles
46  file(i)%fname=''
47 end do
48 end subroutine
49 
50 subroutine findfile(fname,fnum)
51 implicit none
52 ! arguments
53 character(*), intent(in) :: fname
54 integer, intent(out) :: fnum
55 ! local variables
56 integer i
57 if (.not.allocated(file)) then
58  write(*,*)
59  write(*,'("Error(findfile): RAM disk not initialised")')
60  write(*,*)
61  stop
62 end if
63 fnum=0
64 do i=1,maxfiles
65  if (file(i)%fname == fname) then
66  fnum=i
67  return
68  end if
69 end do
70 end subroutine
71 
72 subroutine openfile(fname,fnum)
73 implicit none
74 ! arguments
75 character(*), intent(in) :: fname
76 integer, intent(out) :: fnum
77 ! local variables
78 integer i
79 ! check to see if the file already exists
80 call findfile(fname,fnum)
81 if (fnum /= 0) return
82 ! use the first available file number
83 do i=1,maxfiles
84  if (file(i)%fname == '') then
85 ! assign the filename
86  file(i)%fname=fname
87 ! allocate the record array
88  allocate(file(i)%rec(maxrec))
89  fnum=i
90  return
91  end if
92 end do
93 write(*,*)
94 write(*,'("Error(openfile): too many RAM disk files open : ",I0)') maxfiles
95 write(*,*)
96 stop
97 end subroutine
98 
99 subroutine delfrd(fname)
100 ! this subroutine should not be called from a parallel region
101 implicit none
102 ! arguments
103 character(*), intent(in) :: fname
104 ! local variables
105 integer fnum,i
106 ! determine the file number
107 call findfile(fname,fnum)
108 ! return if the file does not exist
109 if (fnum == 0) return
110 ! erase filename
111 file(fnum)%fname=''
112 ! deallocate associated arrays
113 do i=1,maxrec
114  if (allocated(file(fnum)%rec(i)%dat)) deallocate(file(fnum)%rec(i)%dat)
115 end do
116 deallocate(file(fnum)%rec)
117 end subroutine
118 
119 subroutine putrd(fname,irec,n1,n2,n3,v1,v2,nrv,rva,nzv,zva)
120 ! this subroutine should be called from an OpenMP critical section
121 implicit none
122 ! arguments
123 character(*), intent(in) :: fname
124 integer, intent(in) :: irec
125 integer, optional, intent(in) :: n1,n2,n3
126 real(8), optional, intent(in) :: v1(3),v2(3)
127 integer, optional, intent(in) :: nrv
128 real(8), optional, intent(in) :: rva(*)
129 integer, optional, intent(in) :: nzv
130 complex(8), optional, intent(in) :: zva(*)
131 ! local variables
132 integer fnum,n,i,j
133 ! check that the record number does not exceed the maximum
134 if (irec > maxrec) then
135 ! fail safe by enabling disk writes
136  wrtdisk=.true.
137  return
138 end if
139 ! find the record length in 4-byte words
140 n=0
141 if (present(n1)) n=n+1
142 if (present(n2)) n=n+1
143 if (present(n3)) n=n+1
144 if (present(v1)) n=n+6
145 if (present(v2)) n=n+6
146 if (present(rva)) then
147  if (present(nrv)) then
148  n=n+2*nrv
149  else
150  write(*,*)
151  write(*,'("Error(putrd): missing argument nrv")')
152  write(*,*)
153  stop
154  end if
155 end if
156 if (present(zva)) then
157  if (present(nzv)) then
158  n=n+4*nzv
159  else
160  write(*,*)
161  write(*,'("Error(putrd): missing argument nzv")')
162  write(*,*)
163  stop
164  end if
165 end if
166 ! open the file
167 call openfile(fname,fnum)
168 ! allocate the record data array if required
169 if (allocated(file(fnum)%rec(irec)%dat)) then
170  if (size(file(fnum)%rec(irec)%dat) < n) then
171  deallocate(file(fnum)%rec(irec)%dat)
172  end if
173 end if
174 if (.not.allocated(file(fnum)%rec(irec)%dat)) then
175  allocate(file(fnum)%rec(irec)%dat(n))
176 end if
177 i=1
178 if (present(n1)) then
179  file(fnum)%rec(irec)%dat(i)=n1
180  i=i+1
181 end if
182 if (present(n2)) then
183  file(fnum)%rec(irec)%dat(i)=n2
184  i=i+1
185 end if
186 if (present(n3)) then
187  file(fnum)%rec(irec)%dat(i)=n3
188  i=i+1
189 end if
190 if (present(v1)) then
191  j=i+5
192  file(fnum)%rec(irec)%dat(i:j)=transfer(v1(1:3),[1_4])
193  i=i+6
194 end if
195 if (present(v2)) then
196  j=i+5
197  file(fnum)%rec(irec)%dat(i:j)=transfer(v2(1:3),[1_4])
198  i=i+6
199 end if
200 if (present(rva)) then
201  j=i+2*nrv-1
202  file(fnum)%rec(irec)%dat(i:j)=transfer(rva(1:nrv),[1_4])
203  i=i+2*nrv
204 end if
205 if (present(zva)) then
206  j=i+4*nzv-1
207  file(fnum)%rec(irec)%dat(i:j)=transfer(zva(1:nzv),[1_4])
208 end if
209 end subroutine
210 
211 subroutine getrd(fname,irec,tgs,n1,n2,n3,v1,v2,nrv,rva,nzv,zva)
212 implicit none
213 ! arguments
214 character(*), intent(in) :: fname
215 integer, intent(in) :: irec
216 logical, intent(out) :: tgs
217 integer, optional, intent(out) :: n1,n2,n3
218 real(8), optional, intent(out) :: v1(3),v2(3)
219 integer, optional, intent(in) :: nrv
220 real(8), optional, intent(out) :: rva(*)
221 integer, optional, intent(in) :: nzv
222 complex(8), optional, intent(out) :: zva(*)
223 ! local variables
224 integer fnum,n,i
225 if (present(rva)) then
226  if (.not.present(nrv)) then
227  write(*,*)
228  write(*,'("Error(getrd): missing argument nrv")')
229  write(*,*)
230  stop
231  end if
232 end if
233 if (present(zva)) then
234  if (.not.present(nzv)) then
235  write(*,*)
236  write(*,'("Error(getrd): missing argument nzv")')
237  write(*,*)
238  stop
239  end if
240 end if
241 tgs=.false.
242 if (irec > maxrec) return
243 ! determine the file number
244 call findfile(fname,fnum)
245 ! return unsuccessfully if file is not found or record is unavailable
246 if (fnum == 0) return
247 if (.not.allocated(file(fnum)%rec(irec)%dat)) return
248 n=size(file(fnum)%rec(irec)%dat)
249 i=1
250 if (present(n1)) then
251  if (n < 1) return
252  n1=file(fnum)%rec(irec)%dat(i)
253  i=i+1
254  n=n-1
255 end if
256 if (present(n2)) then
257  if (n < 1) return
258  n2=file(fnum)%rec(irec)%dat(i)
259  i=i+1
260  n=n-1
261 end if
262 if (present(n3)) then
263  if (n < 1) return
264  n3=file(fnum)%rec(irec)%dat(i)
265  i=i+1
266  n=n-1
267 end if
268 if (present(v1)) then
269  if (n < 6) return
270  v1(1:3)=transfer(file(fnum)%rec(irec)%dat(i:i+5),v1(1:3))
271  i=i+6
272  n=n-6
273 end if
274 if (present(v2)) then
275  if (n < 6) return
276  v2(1:3)=transfer(file(fnum)%rec(irec)%dat(i:i+5),v2(1:3))
277  i=i+6
278  n=n-6
279 end if
280 if (present(rva)) then
281  if (n < 2*nrv) return
282  rva(1:nrv)=transfer(file(fnum)%rec(irec)%dat(i:i+2*nrv-1),rva(1:nrv))
283  i=i+2*nrv
284  n=n-2*nrv
285 end if
286 if (present(zva)) then
287  if (n < 4*nzv) return
288  zva(1:nzv)=transfer(file(fnum)%rec(irec)%dat(i:i+4*nzv-1),zva(1:nzv))
289 end if
290 ! flag the get operation as successful
291 tgs=.true.
292 end subroutine
293 
294 subroutine rdstatus
295 ! this subroutine should not be called from a parallel region
296 implicit none
297 ! local variables
298 integer nf,nr,i,j
299 integer(8) m,n
300 write(*,*)
301 write(*,'("Info(rdstatus):")')
302 if (.not.allocated(file)) then
303  write(*,'(" RAM disk not initialised")')
304  return
305 end if
306 nf=0
307 n=0
308 do i=1,maxfiles
309  if (file(i)%fname /= '') then
310  write(*,*)
311  write(*,'(" Filename : ",A)') file(i)%fname
312  nf=nf+1
313  nr=0
314  m=0
315  do j=1,maxrec
316  if (allocated(file(i)%rec(j)%dat)) then
317  nr=nr+1
318  m=m+size(file(i)%rec(j)%dat)
319  end if
320  end do
321  n=n+m
322  write(*,'(" number of records : ",I0)') nr
323  write(*,'(" total number of bytes : ",I0)') 4*m
324  end if
325 end do
326 write(*,*)
327 write(*,'(" Number of files on RAM disk : ",I0)') nf
328 write(*,'(" Total number of bytes used by RAM disk : ",I0)') 4*n
329 end subroutine
330 
331 end module
332 
logical ramdisk
Definition: modramdisk.f90:9
logical wrtdisk
Definition: modramdisk.f90:15
subroutine putrd(fname, irec, n1, n2, n3, v1, v2, nrv, rva, nzv, zva)
Definition: modramdisk.f90:120
logical wrtdisk0
Definition: modramdisk.f90:15
type(file_t), dimension(:), allocatable, private file
Definition: modramdisk.f90:29
subroutine rdstatus
Definition: modramdisk.f90:295
subroutine getrd(fname, irec, tgs, n1, n2, n3, v1, v2, nrv, rva, nzv, zva)
Definition: modramdisk.f90:212
subroutine, private findfile(fname, fnum)
Definition: modramdisk.f90:51
subroutine delfrd(fname)
Definition: modramdisk.f90:100
subroutine initrd
Definition: modramdisk.f90:37
subroutine, private openfile(fname, fnum)
Definition: modramdisk.f90:73
integer, parameter, private maxfiles
Definition: modramdisk.f90:11
integer, parameter, private maxrec
Definition: modramdisk.f90:13