- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Hello,
I have a file containing an ID which is INTEGER*4 and three coordinates variables for that ID which are all REAL*8 like the following as an example (C:\\TEMP\\NODES.TXT):
227499, 0.658436716, 12.1055336, -2.70311999
Also I have another file which contains four INTEGER*4 variables like the following (C:\\TEMP\\ELEMENTS.TXT):
528594, 232407, 231854, 231853
I have used the following code to convert the sequential file to a DIRECT ACCESS file. The number of records are variable each time I run the code. Could you please let me know how I should choose the RECORD LENGTH for those two files? Even I set REC=10 it works perectly with like 500,000 records.
PROGRAM WRITE_AS_DIRECT
INTEGER*4 NODEID, I
INTEGER*4 ELEMID, NODEID1, NODEID2, NODEID3
REAL*8 X, Y, Z
OPEN(UNIT=1,FILE='C:\\TEMP\\NODES.TXT')
OPEN(UNIT=2,FILE='C:\\TEMP\\NODESDIRECT.TXT',
1 ACCESS='DIRECT',FORM='UNFORMATTED',RECL=10,ACTION='WRITE')
I=1
DO WHILE (.NOT.EOF(1))
READ(1,*) NODEID, X, Y, Z
WRITE(2,REC=NODEID) X, Y, Z
I=I+1
ENDDO
CLOSE(1)
CLOSE(2)
OPEN(UNIT=1,FILE='C:\\TEMP\\ELEMENTS.TXT')
OPEN(UNIT=2,FILE='C:\\TEMP\\ELEMENTSDIRECT.TXT',
1 ACCESS='DIRECT',FORM='UNFORMATTED',RECL=10,ACTION='WRITE')
I=1
DO WHILE (.NOT.EOF(1))
READ(1,*) ELEMID, NODEID1, NODEID2, NODEID3
WRITE(2,REC=ELEMID) NODEID1, NODEID2, NODEID3
I=I+1
ENDDO
CLOSE(1)
CLOSE(2)
END
Thanks,
Ahmad
I have a file containing an ID which is INTEGER*4 and three coordinates variables for that ID which are all REAL*8 like the following as an example (C:\\TEMP\\NODES.TXT):
227499, 0.658436716, 12.1055336, -2.70311999
Also I have another file which contains four INTEGER*4 variables like the following (C:\\TEMP\\ELEMENTS.TXT):
528594, 232407, 231854, 231853
I have used the following code to convert the sequential file to a DIRECT ACCESS file. The number of records are variable each time I run the code. Could you please let me know how I should choose the RECORD LENGTH for those two files? Even I set REC=10 it works perectly with like 500,000 records.
PROGRAM WRITE_AS_DIRECT
INTEGER*4 NODEID, I
INTEGER*4 ELEMID, NODEID1, NODEID2, NODEID3
REAL*8 X, Y, Z
OPEN(UNIT=1,FILE='C:\\TEMP\\NODES.TXT')
OPEN(UNIT=2,FILE='C:\\TEMP\\NODESDIRECT.TXT',
1 ACCESS='DIRECT',FORM='UNFORMATTED',RECL=10,ACTION='WRITE')
I=1
DO WHILE (.NOT.EOF(1))
READ(1,*) NODEID, X, Y, Z
WRITE(2,REC=NODEID) X, Y, Z
I=I+1
ENDDO
CLOSE(1)
CLOSE(2)
OPEN(UNIT=1,FILE='C:\\TEMP\\ELEMENTS.TXT')
OPEN(UNIT=2,FILE='C:\\TEMP\\ELEMENTSDIRECT.TXT',
1 ACCESS='DIRECT',FORM='UNFORMATTED',RECL=10,ACTION='WRITE')
I=1
DO WHILE (.NOT.EOF(1))
READ(1,*) ELEMID, NODEID1, NODEID2, NODEID3
WRITE(2,REC=ELEMID) NODEID1, NODEID2, NODEID3
I=I+1
ENDDO
CLOSE(1)
CLOSE(2)
END
Thanks,
Ahmad
1 Solution
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
You are not using Fortran 77. Apparently, you are using Intel Fortran, which is a Fortran-95 (well, almost Fortran-2003) compiler. The proof of that is that you are already using direct unformatted files, which are a Fortran-90 feature.
You are using the fixed-form code, but it is not equal to "Fortran 77". Fixed-form is still valid Fortran-90, Fortran-95 and Fortran-2003. The standard to which the code conforms is dictated by features it uses, not by the source form.
By the way, this Jim's solution is not good in a general case:
You are using the fixed-form code, but it is not equal to "Fortran 77". Fixed-form is still valid Fortran-90, Fortran-95 and Fortran-2003. The standard to which the code conforms is dictated by features it uses, not by the source form.
By the way, this Jim's solution is not good in a general case:
[fortran]SIZEOF_RECORD_DATA = SIZEOF(X) + SIZEOF(Y) + SIZEOF(Z) [/fortran]Because of padding, you may potentially end up with a record smaller than required. Instead, use the Fortran feature specially designed for that:
[bash]INQUIRE(IOLENGTH=SIZEOF_RECORD_DATA) X, Y, Z[/bash]
Link Copied
6 Replies
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Hello
The record length must be set to the length of datas written in each record. In the first case, 3 real*8 implies a record length of 24, and in the second 3 integer*4 implies 12.
The record length must be set to the length of datas written in each record. In the first case, 3 real*8 implies a record length of 24, and in the second 3 integer*4 implies 12.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Thanks. Does it matter if I set a bigger record length and use for example half of it (in case I switch REAL*8 to REAL)?
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Quoting Ahmad Falahatpisheh
Thanks. Does it matter if I set a bigger record length and use for example half of it (in case I switch REAL*8 to REAL)?
Compute the record length
[bash]PROGRAM WRITE_AS_DIRECT INTEGER*4 NODEID, I INTEGER*4 ELEMID, NODEID1, NODEID2, NODEID3 ! RECORD DATA REAL*8 X, Y, Z ! END OF RECORD DATA INTEGER :: SIZEOF_RECORD_DATA SIZEOF_RECORD_DATA = SIZEOF(X) + SIZEOF(Y) + SIZEOF(Z) OPEN(UNIT=1,FILE='C:TEMPNODES.TXT') OPEN(UNIT=2, & & FILE='C:TEMPNODESDIRECT.TXT', & & ACCESS='DIRECT', & & FORM='UNFORMATTED', & & RECL=SIZEOF_RECORD_DATA, & & ACTION='WRITE') I=1 DO WHILE (.NOT.EOF(1)) READ(1,*) NODEID, X, Y, Z WRITE(2,REC=NODEID) X, Y, Z I=I+1 ENDDO CLOSE(1) CLOSE(2) OPEN(UNIT=1,FILE='C:TEMPELEMENTS.TXT') OPEN( UNIT=2, & & FILE='C:TEMPELEMENTSDIRECT.TXT', & & ACCESS='DIRECT', & & FORM='UNFORMATTED', & & RECL=SIZEOF_RECORD_DATA, & & ACTION='WRITE') I=1 DO WHILE (.NOT.EOF(1)) READ(1,*) ELEMID, NODEID1, NODEID2, NODEID3 WRITE(2,REC=ELEMID) NODEID1, NODEID2, NODEID3 I=I+1 ENDDO CLOSE(1) CLOSE(2) END [/bash]
It will be less error prone if you place the record data into a user defined type.
type iorec_t
real*8 :: X, Y, Z
end type iorec_t
type(iorec_t) :: iorec
OPEN(UNIT=1,FILE='C:\TEMP\NODES.TXT')
OPEN(UNIT=2, &
& FILE='C:\TEMP\NODESDIRECT.TXT', &
& ACCESS='DIRECT', &
& FORM='UNFORMATTED', &
& RECL=SIZEOF(iorec), &
& ACTION='WRITE')
I=1
DO WHILE (.NOT.EOF(1))
READ(1,*) NODEID, iorec%X, iorec%Y, iorec%Z
WRITE(2,REC=NODEID) iorec
I=I+1
ENDDO
...
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
It really looks professional. Unfortunately, I am using FORTRAN77. Do you think I can pply the same concept?
Thanks,
Ahmad
Thanks,
Ahmad
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
You are not using Fortran 77. Apparently, you are using Intel Fortran, which is a Fortran-95 (well, almost Fortran-2003) compiler. The proof of that is that you are already using direct unformatted files, which are a Fortran-90 feature.
You are using the fixed-form code, but it is not equal to "Fortran 77". Fixed-form is still valid Fortran-90, Fortran-95 and Fortran-2003. The standard to which the code conforms is dictated by features it uses, not by the source form.
By the way, this Jim's solution is not good in a general case:
You are using the fixed-form code, but it is not equal to "Fortran 77". Fixed-form is still valid Fortran-90, Fortran-95 and Fortran-2003. The standard to which the code conforms is dictated by features it uses, not by the source form.
By the way, this Jim's solution is not good in a general case:
[fortran]SIZEOF_RECORD_DATA = SIZEOF(X) + SIZEOF(Y) + SIZEOF(Z) [/fortran]Because of padding, you may potentially end up with a record smaller than required. Instead, use the Fortran feature specially designed for that:
[bash]INQUIRE(IOLENGTH=SIZEOF_RECORD_DATA) X, Y, Z[/bash]
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Jugoslav,
Thanks for pointing this out.
On this subject, and for clarification, if padding is involved in the I/O then wouldn't it also be dependent on the mode in which and machine on whicha file were opened? If so then wouldn't the INQUIRE also require an I/O unit? In the special case of the user's sample code reals were written and padds typically wouldn't have been used. Padd might appear when writing user defined type or LOGICAL or some CHARACTER variables, but then these would also cause portibility problems with the binary files (one system requiring machine word alignment the other not).
Jim
Thanks for pointing this out.
On this subject, and for clarification, if padding is involved in the I/O then wouldn't it also be dependent on the mode in which and machine on whicha file were opened? If so then wouldn't the INQUIRE also require an I/O unit? In the special case of the user's sample code reals were written and padds typically wouldn't have been used. Padd might appear when writing user defined type or LOGICAL or some CHARACTER variables, but then these would also cause portibility problems with the binary files (one system requiring machine word alignment the other not).
Jim
Reply
Topic Options
- Subscribe to RSS Feed
- Mark Topic as New
- Mark Topic as Read
- Float this Topic for Current User
- Bookmark
- Subscribe
- Printer Friendly Page