Fortran90: read xyz file

  • Fortran
  • Thread starter typeon
  • Start date
  • #1
4
0
Hi everyone,

I am kind of new in fortran90 and I am struggling with writing this basic programme:
I have an input file with a fixed format . It looks like this:

c 23.345 45.342 34.345
c 12.345 56.235 67.234
c 45.567 44.345 78.345
c 56.567 78.563 97.342

where the first column is always a character and columns 2 to 4 are real numbers.
Since, it is a mixture of types I am wondering how to programme this so that it reads the information from an input file : cartesian.xyz
Should I use "derived data types" to define a matrix that is composed of one character and 3 real numbers? or is there another way?.

Thanks!!!
 

Answers and Replies

  • #2
35,063
6,796
Hi everyone,

I am kind of new in fortran90 and I am struggling with writing this basic programme:
I have an input file with a fixed format . It looks like this:

c 23.345 45.342 34.345
c 12.345 56.235 67.234
c 45.567 44.345 78.345
c 56.567 78.563 97.342

where the first column is always a character and columns 2 to 4 are real numbers.
Since, it is a mixture of types I am wondering how to programme this so that it reads the information from an input file : cartesian.xyz
Should I use "derived data types" to define a matrix that is composed of one character and 3 real numbers? or is there another way?.
You can't have a matrix that is composed of different types (i.e., characters and reals). You can, however, define a structure that can hold a character and three real numbers, and then define an array whose members are structures.

You didn't mention what your program is going to do with the values in the input file, so you may or may not need to read all of the file contents into memory (into an array as described above). It might be sufficient to read in one row of values, do you computations, and move on to the next row to do some more work.
 
  • #3
4
0
Hi,

The input file is a molecule, a finite flat sheet of graphene. So once the whole input is read a table with each carbon atom and its neighbours is generated. It will also calculate whether the carbon atom is in the middle or at the edge of the flake. In short, I really think it has to read the whole input and keep it in the memory.
Can I generate a structure that can hold a character and three real numbers using the following module?

module test
type mytype
sequence
character(len=6):: carbon
integer :: x
integer :: y
integer :: z
end type mytype
end module test
 
  • #4
35,063
6,796
Hi,

The input file is a molecule, a finite flat sheet of graphene. So once the whole input is read a table with each carbon atom and its neighbours is generated. It will also calculate whether the carbon atom is in the middle or at the edge of the flake. In short, I really think it has to read the whole input and keep it in the memory.
Can I generate a structure that can hold a character and three real numbers using the following module?

module test
type mytype
sequence
character(len=6):: carbon
integer :: x
integer :: y
integer :: z
end type mytype
end module test

More like this. In your first post you showed the numeric data as being real, not integer, so I changed the fields to take this into account.

BTW, the carbon field as you have it doesn't hold a single character - it can hold six characters.
Code:
module test
type molecule_position
   sequence
   character(len=6):: carbon
   real*8  :: x
   real*8  :: y
   real*8  :: z
end type molecule_position
end module test[/QUOTE]

You can define an array whose elements are of this type.
 
  • #5
4
0
I have made the programme and I have managed to read the xyz input ( file : cartesian) and print it to the
unit 55.: fort.55

module test
type molecule_position
sequence
character(len=1):: carbon
real*8 :: x
real*8 :: y
real*8 :: z
end type molecule_position
end module test

program xyz
use test
implicit none
! here I define the 4 lines of my xyz file
type(molecule_position) :: line1
type(molecule_position) :: line2
type(molecule_position) :: line3
type(molecule_position) :: line4

! I open the file with the coordinates and read every line
open(12,file='cartesian', status='old')
read(12,*) line1, line2, line3, line4
! This format I made it but it s not working
!1 format(A1,1x,f6.3,1x,f6.3,1x,f6.3)

write(55,*) line1, line2, line3, line4
end program xyz

1) Do I have to define each line every time I want to add a new line or is there a way
to tell the code that the number of lines is, say, 50, and I want it to create 50 variables like
type(molecule_position) : from line1 to line50

2) I tried to print it out with only 3 decimals but my format is faulty

c 23.344999999999999 45.341999999999999 34.344999999999999
c 12.345000000000001 56.234999999999999 67.233999999999995
c 45.567000000000000 44.344999999999999 78.344999999999999
c 56.567000000000000 78.563000000000002 97.341999999999999
 
  • #6
35,063
6,796
You can't READ a whole derived type at once - you need to READ a field at a time. To access the fields of a derived type, use %. This code should read one line of data in your input file.

Code:
read (12, 1) line1%carbon, line1%x, line1%y, line1%z
1 format(A1,1x,f6.3,1x,f6.3,1x,f6.3)

Do the same sort of thing to write out the data. With these changes, your format statements should work.

It's been a long while since I did any fortran programming, and I don't recall doing anything with derived types. The information I presented here comes from a fortran 90 tutorial I found at http://web.mse.uiuc.edu/courses/mse485/comp_info/derived.html [Broken].
 
Last edited by a moderator:

Related Threads on Fortran90: read xyz file

Replies
11
Views
6K
Replies
5
Views
2K
Replies
2
Views
755
  • Last Post
Replies
2
Views
3K
  • Last Post
Replies
5
Views
6K
Replies
4
Views
6K
Replies
5
Views
18K
Replies
5
Views
4K
Top