Dismiss Notice
Join Physics Forums Today!
The friendliest, high quality science and math community on the planet! Everyone who loves science is here!

Open command on Fortran

  1. Aug 7, 2010 #1
    Hello there. I've doing a program that I do not know how many files will be needed, because it'll depend on user's choice. So, how to name them?

    I tought that a command like, where n is a user-input number

    Code (Text):
    Do While (i .LE. n)
    Open (Unit=i, File=i'.dat')
    i=i+1
    EndDo
    Would be enough, but I can't name my files this way. Any ideas?
     
  2. jcsd
  3. Aug 8, 2010 #2
    I've been thinking about this program (many thanks to emes) and tought thet I could do something like this

    Code (Text):

    Subroutine Opener (n,i)
    Implicit None
    Integer n,i
    Character (LEN=15) :: files
    Open (unit=500,File='Files1.dat')
    Open (unit=501,File='Files2.dat')
    i=1
    Do While (i .LE. n)
        Write (500,*) i,'.dat'
        Write (501,*) 'mov',i,'.dat'
        i=i+1
    End
    i=1
    Do While (i .LE. n)
        Read (500,*) files
        Open (Unit=i,File=files)
        Read (501,*)
        Open (Unit=i+n,File=files)
        i=i+1
    EndDo
    End
     
    But would it read line after line of the files?

    Hehe. I've turned this Open problem into a Read one.
     
  4. Aug 8, 2010 #3

    minger

    User Avatar
    Science Advisor

    I have a post somewhere on here as a way to do it. Basically, you can use the WRITE command to concatenate a string with a variable. You can then OPEN the file with the filename as the variable. It's something like this:

    Code (Text):

    DO i=1,10
      WRITE(fname,'I2,A4') i,'.dat'
      OPEN(10,file=filename,form='formatted')
      ...
    END DO
     
     
  5. Aug 8, 2010 #4
    When I use

    Code (Text):

    i=1
    Do While (i .LE. n)
        Write (500,*) i,'.dat'
        Write (501,*) 'mov',i,'.dat'
        i=i+1
    End
     
    I'll have a file like this

    Code (Text):

    1.dat
    2.dat
    3.dat
    .
    .
    .
    n.dat
     
    When I read it with

    Code (Text):

    i=1
    Do While (i .LE. n)
        Read (500,*) files(i)
        Open (Unit=i,File=files)
        i=i+1
    EndDo
     
    Will I get a array with like 1.dat, on index 1, 2.dat, on index 2, ... n.dat, on index n, or I'll receive '1.dat 2.dat 3.dat ... n.dat' in every index?
     
  6. Aug 9, 2010 #5
    I have solved many issues on this program already, but new ones keep rising.

    On this 'subprogram', when it goes into the third loop it can't get out. But it does open all files it should open

    Code (Text):

    Program Lennard2
    Implicit None
    Double Precision dt,e,sigma,x(20),y(20),vx(20),vy(20),tet(20),omeg(20),&
    rad(20),mass(20)
    Integer n,i,show
    Character (LEN=15) :: files(20),files2(20)
    Call Inserter (dt,e,sigma,x,y,vx,vy,tet,omeg,rad,mass,n,i,show)
    Call Opener (n,i,files,files2)
    End

    Subroutine Opener (n,i,files,files2)
    Implicit None
    Integer n,i
    Character (LEN=15) :: files(20),files2(20)
    i=01
    10 format (i2,A4)
    20 format (i2,A7)
    Open (Unit=500,File="uia.dat",Action='Write')
    Open (Unit=501,File="duia.dat",Action='Write')
    Do While (i .LE. n)
        Write (500,10) i,'.dat'
        Write (501,20) i,'mov.dat'
        Write (*,*) 'First Loop'
        i=i+1
    EndDo
    Close (Unit=500)
    Close (Unit=501)
    i=1
    Open (Unit=500,File="uia.dat",Action='Read')
    Open (Unit=501,File="duia.dat",Action='Read')
    Do While (i .LE. n)
        Read (500,*) files(i)
        Read (501,*) files2(i)
        Write (*,*) 'Second Loop'
        i=i+1
    EndDo
    i=1
    Do While (i .LE.n)
        Open (Unit=i,File=files(i))
        Open (Unit=i+n,File=files2(i))
        Write (*,*) 'Third Loop'
        i=i+1
    EndDo
    i=1
    Do While (i .LE. n)
        Write (i,*) i
        Write (i+n,*) i+n
        i=i+1
        Write (*,*) 'Forth Loop'
    EndDo
    Write (*,*) 'Opener'
    End

    Subroutine Inserter (dt,e,sigma,x,y,vx,vy,tet,omeg,rad,mass,n,i,show)
    Implicit None
    Double Precision dt,e,sigma,x(20),y(20),vx(20),vy(20),tet(20),omeg(20),&
    rad(20),mass(20)
    Integer n,i,show
    Write (*,*) 'Insert time step'
    Read (*,*) dt
    Write (*,*) 'Insert sigma (distance at which the inter-particle &
    potential is zero)'
    Read (*,*) sigma
    Write (*,*) 'Insert epislon (depth of the potential well)'
    Read (*,*) e
    Write (*,*) 'Insert steps between output'
    Read (*,*) show
    200 Write (*,*) 'Insert how many particles (2~20)'
    Read (*,*) n
    If (n .GT. 20) then
    Write (*,*) 'Invalid Input'
    Go to 200
    End If
    If (n .LT. 2) then
    Write (*,*) 'Invalid Input'
    Go to 200
    End If
    i=1
    Do While (i .LE. n)
    Write (*,*) "Insert ",i," disk's mass"
    Read (*,*) mass(i)
    Write (*,*) "Insert ",i," disk's radius"
    Read (*,*) rad(i)
    Write (*,*) "Insert ",i," disk's initial vertical speed"
    Read (*,*) vy(i)
    Write (*,*) "Insert ",i," disk's initial horizontal speed"
    Read (*,*) vx(i)
    Write (*,*) "Insert ",i," disk's initial vertical position"
    Read (*,*) y(i)
    Write (*,*) "Insert ",i," disk's initial horizontal positon"
    Read (*,*) x(i)
    Write (*,*) "Insert ",i," disk's initial angular speed"
    Read (*,*) omeg(i)
    Write (*,*) "Insert ",i," disk's initial angular position"
    Read (*,*) tet(i)
    i=i+1
    Write(*,*) 'Inserter'
    EndDo
    End
     
    Strangely, when I use up to 4 particles, it works ok. But anything above that won't do the job.
     
  7. Aug 9, 2010 #6

    minger

    User Avatar
    Science Advisor

    You cannot open an array of files in one unit number. Each unit number must correspond to a single file that its operating on. Reading the files in as you described won't work...for several reasons. You can use the same unit number. Just close the file at the end of the do-loop and reopen it after you've changed the filename. After you write out the files, the read would look like:
    Code (Text):

    DO i=1,n
      !-- writing routines
    END DO

    DO i=1,n
      WRITE(fname,'A3,I2,A4') 'mov',i,'.dat'
      OPEN(10,file=fname,form='formatted')
      !--Read the file here
      CLOSE(10)
    END DO
     
    Be careful using unit numbers above 99. I wasn't even sure that you could do that. I'm fairly sure that many compilers will have issues with it.

    Looking through your code it appears you have some issues. Firstly, you have a DO loop where i < n, but n doesn't appear to be defined, nor does it change. Your arrays that hold the data are only dimensioned to 20, but your program is written so that a general number, n, can be called. If you want this, you should change your arrays to ALLOCATABLE.
     
  8. Aug 9, 2010 #7
    I fail to see where I was trying to open twice using the same unit. Could you show me more detailed? On the subject of the array of 20, I've put a few Ifs on Inserter to deal with that, but I'll make some research on Allocatables Arrays, it seems quite interesting.

    Code (Text):

    .
    .
    .
    200 Write (*,*) 'Insert how many particles (2~20)'
    Read (*,*) n
    If (n .GT. 20) then
    Write (*,*) 'Invalid Input'
    Go to 200
    End If
    If (n .LT. 2) then
    Write (*,*) 'Invalid Input'
    Go to 200
    End If
    .
    .
    .
     
     
  9. Aug 9, 2010 #8

    minger

    User Avatar
    Science Advisor

    I didn't say that you were opening two files with the same unit number, I said that in your example, you were trying to open an array of files, quote:
    Code (Text):

    i=1
    Do While (i .LE. n)
        Read (500,*) files(i)
        [b]Open (Unit=i,File=files)[/b]
        i=i+1
    EndDo
     
    files here is defined as an array. This implicitly means that you're attempting to open up all files, (files(i),i=1,imax).
     
Share this great discussion with others via Reddit, Google+, Twitter, or Facebook