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