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

Array reading error when opening multiple files in Fortran

  1. Dec 27, 2012 #1
    Guys. I really need help. I have been working in this little problem for hours. I had a problem in array reading when I opened more than 1 files, it seems like an array with different names mixed each other. Here is my code

    Code (Text):

    integer, parameter::size=11
    real, dimension(101)    ::   cldata, alphadata
    real, dimension(size)    ::   circ
    integer:: i, j, nvals=0, nvals2=0, nvals3=0, status
    Open (Unit=1, File='circdata.txt', status='old', Action='Read')
    fileopen1: IF (status==0) then
        Write (*,1000) status
        1000 format (1x,'file alphadata open success--status = ',I6)
        do
            read(1,*,iostat=status) temp    !Get value
            if (status/=0) exit             !Exit on end of data
            nvals=nvals+1                   !Bump count
            circ(nvals)=temp                !Save value in array
        end do
    else fileopen1
    Write (*,1050) status
    1050 format (1x,'file open failed--status = ',I6)
    end if fileopen1

    Open (Unit=2, File='alphadata.txt', status='old', Action='Read', Iostat=status)
    fileopen2: IF (status==0) then
        Write (*,2000) status
        2000 format (1x,'file alphadata open success--status = ',I6)
        do
            read(2,*,iostat=status) temp    !Get value
            if (status/=0) exit             !Exit on end of data
            nvals2=nvals2+1               !Bump count
            alphadata(nvals2)=temp     !Save value in array
        end do
    else fileopen2
    Write (*,1060) status
    1060 format (1x,'file open failed--status = ',I6)
    end if fileopen2

    Open (Unit=3, File='cldata.txt', status='old', Action='Read', Iostat=status)
    fileopen3: IF (status==0) then
        Write (*,3000) status
        3000 format (1x,'file cldata open success--status = ',I6)
        do
            read(3,*,iostat=status) temp    !Get value
            if (status/=0) exit             !Exit on end of data
            nvals3=nvals3+1                 !Bump count
            cldata(nvals3)=temp             !Save value in array
        end do
    else fileopen3
    Write (*,1070) status
    1070 format (1x,'file open failed--status = ',I6)
    end if fileopen3
     
    I have 2 arrays, A and B that I want to calculate, the A just need the file in open unit 1, and the last one need data from the file in open unit 2 and 3. When I deleted the open unit 2 and 3, my program worked just fine. But I needed those files for calculating array B. I had tried to put this last 2 opening syntax (unit 2 and 3) after the line to calculate the array A, but the program didn't work like it's supposed to be, element in array A became messy. I am really confused why this could happen, because I thought file in unit 2 and 3 don't relate with array A. Is there anything wrong with my syntax? or is it because my compiler, I am using the latest gfortran? Is there any other way that I can use?

    Thanks in advance guys.
     
  2. jcsd
  3. Dec 28, 2012 #2

    SteamKing

    User Avatar
    Staff Emeritus
    Science Advisor
    Homework Helper

    One thing which stands out. You have several named IF blocks like this:

    fileopen1: IF blah blah

    Else fileopen1
    blah blah

    End if fileopen1

    I think you only need the fileopen1: label on the initial IF and End if fileopen1, but the Else statements in between do not need to refer to the initial label on the IF statement. The else statements are understood to be contained within the IF block and the label is not needed.
     
  4. Dec 28, 2012 #3
    just quick visual inspection (not compiling or trying to actually fix things)...

    is this the entire program?...I don't see the "end program" statement.

    the very first "Open" statement does not have the argument "iostat", so, I am not sure what the value of "status" is on the next line...

    by the way, it is best to declare all your variables.

    you seem to be re-using the variable "status" for various things...like message from opening file and message from reading data from the file...I would separate those things.

    Also, I don't remember what the default line length is...some of you lines are longer than 72...are you passing a switch at compile time to allow for longer lines?
     
  5. Dec 28, 2012 #4
    Hi steamking. Thanks for your response. Yeah, it's correct, I have tried it and it still work. I just follow this style of writing from a book. I am really new in fortran and still lacking in doing improvement.
     
  6. Dec 28, 2012 #5
    Hi gsal. Thanks for your response. It's just a part of codes, and I forget to post argument iostat in copying. About the default line, I have read about that issue in Chapman book, fortran 95/2003 for scientist and engineer, the default line length is 132 characters long.

    Anyway after several trying, I have known the problem happening because I coincidentally change the option build target to debug option. After I change it back to release, It work normal again. Why debug option could cause this problem? I just googled and find out that debug option work just like debugger.

    But I found a new problem regarding to this array. It's no more about opening file (I guess), but the problem happened if I wrote down an array to monitor that it will lead to mess up another array in previous operation. But the odd thing was my previous array works normal if I didnt write the new one to monitor although I still calculated it. Here is I include my full coding.

    Code (Text):

    Program Non_Linear_Lifting_Line

    implicit none       !Force explicit declaration of variables

    !Data dictionary: variable types, definitions, units
    integer:: i, j, nvals=0, nvals2=0, nvals3=0, status !just index
    integer, parameter::size=11    !setting size of array
    real::deltay=1.1, PI=3.14285, k, V=30  !several variables
    real::temp, temp2, final, initial !several variables
    real, dimension(101)    ::   cldata, alphadata !AOA and Cl of Airfoil
    real, dimension(size)   ::   alphai        !Induced angle of attack
    real, dimension(size)   ::   alphaeff      !Effective angle of attack
    real, dimension(size)   ::   circ !Circulation
    real, dimension(size)   ::   alpha !Angle of attack
    real, dimension(size)   ::   cl  !Cl for each spanwise
    integer,dimension(size) ::   y  !Length of each spanwise

    !Data dictionary: array data of y
    y=(/(i,i=-5,5)/)

    !Open and read data dictionary: array data of circulation
    Open (Unit=1, File='circdata.txt', status='old', &
    Action='Read', iostat=status)
    fileopen1: IF (status==0) then
        Write (*,1000) status
        1000 format (1x,'file circdata open success--status = ',I6)
        do
            read(1,*,iostat=status) temp    !Get value
            if (status/=0) exit             !Exit on end of data
            nvals=nvals+1                   !Bump count
            circ(nvals)=temp                !Save value in array
        end do
    else
    Write (*,1050) status
    1050 format (1x,'file open failed--status = ',I6)
    end if fileopen1

    !Input data for angle of attack condition
    write(*,*) 'Input angle of attack (in deg): '
    read(*,*) alpha(1)
    do i=1,11
        alpha(i)=alpha(1)
    end do

    !Input data for velocity of flight condition
    Write (*,*) 'Input velocity of flight (in m/s): '
    read(*,*) V

    !outest: do
    !SIMPSON'S RULE TO FIND INDUCED ALPHA
    !Just a constant
    do i=1,11
        Write(*,*) 'circ = ', circ(i)
        Write(*,*) 'y = ', y(i)
    end do

    k=deltay/(12*PI*V)
    !For spanwise station 1 to 6
    do i=1, 6
        temp=alphai(i)
        temp2=y(i)
        if (temp2==y(1)) then
            temp2=temp2*0.01
        elseif (temp2==y(11)) then
            temp2=temp2*0.01
        end if
        initial=(((circ(2)-circ(1))/deltay)/(temp2-y(1)))
        final=(((circ(11)-circ(10))/deltay)/(temp2-y(11)))
        do j=1, 5
            if (temp2==y(2*j)) then
                temp2=temp2*0.69
            elseif (temp2==y(6)) then
                temp2=temp2+0.05
            end if
            temp=temp+4*(((circ(2*j+1)-circ(2*j))/deltay)/(temp2-y(2*j)))
        end do
        do j=1,4
            if (temp2==y(2*j+1)) then
               temp2=temp2*0.1
            elseif (temp2==y(6)) then
               temp2=temp2+0.1
            end if
            temp=temp+2*(((circ(2*j+2)-circ(2*j+1))/deltay)/(temp2-y(2*j+1)))
        end do
        alphai(i)=k*(temp+initial+final)
    end do
    !For spanwise station 7 to 11
    do i=7, 11
        temp=alphai(i)
        temp2=y(i)
        if (temp2==y(1)) then
            temp2=temp2*0.01
        elseif (temp2==y(11)) then
            temp2=temp2*0.01
        end if
        initial=(((circ(2)-circ(1))/deltay)/(temp2-y(1)))
        final=(((circ(11)-circ(10))/deltay)/(temp2-y(11)))
        do j=1, 5
            if (temp2==y(12-2*j)) then
                temp2=temp2*0.69
            elseif (temp2==y(6)) then
                temp2=temp2+0.1
            end if
            temp=temp+4*(((circ(2*j+1)-circ(2*j))/deltay*(-1))/(temp2-y(12-2*j)))
        end do
        do j=1,4
            if (temp2==y(11-2*j)) then
               temp2=temp2*0.1
            elseif (temp2==y(6)) then
               temp2=temp2+0.1
            end if
            temp=temp+2*(((circ(2*j+2)-circ(2*j+1))/deltay*(-1))/(temp2-y(11-2*j)))
        end do
        alphai(i)=k*(temp+initial+final)
    end do
    !Write out alphai
    do i=1,11
        Write(*,*) 'alphai = ', alphai(i)
    end do

    !Finding alphaeff
    effective: do i=1,11
        alphaeff(i)=alpha(i)-alphai(i)
        alphaeff(i)=int(alphaeff(i)*10)/10    !Rounding to 1 decimal
    end do effective
    do i=1,11
        Write(*,*) 'alphaeff = ', alphaeff(i)
    end do

    !Open and Read data dictionary: array data of alphadata
    Open (Unit=2, File='alphadata.txt', status='old', &
    Action='Read', Iostat=status)
    fileopen2: IF (status==0) then
        Write (*,2000) status
        2000 format (1x,'file alphadata open success--status = ',I6)
        do
            read(2,*,iostat=status) temp    !Get value
            if (status/=0) exit             !Exit on end of data
            nvals2=nvals2+1                 !Bump count
            alphadata(nvals2)=temp          !Save value in array
        end do
    else
    Write (*,1060) status
    1060 format (1x,'file open failed--status = ',I6)
    end if fileopen2

    !Open and Read data dictionary: array data of cldata
    Open (Unit=3, File='cldata.txt', status='old', &
    Action='Read', Iostat=status)
    fileopen3: IF (status==0) then
        Write (*,3000) status
        3000 format (1x,'file cldata open success--status = ',I6)
        do
            read(3,*,iostat=status) temp    !Get value
            if (status/=0) exit             !Exit on end of data
            nvals3=nvals3+1                 !Bump count
            cldata(nvals3)=temp             !Save value in array
        end do
    else
    Write (*,1070) status
    1070 format (1x,'file open failed--status = ',I6)
    end if fileopen3

    !Matching alphaeff with (Cl)n from JavaFoil
    Matching: do i=1,11
        temp=alphaeff(i)
        do j=1,101
            if(alphadata(j)==temp) then
                cl(i)=cldata(j)
            end if
        end do
    end do Matching

    Write (*,*) 'It"s still okay so far'

    !Problem doesnt happen if I deleted this code block
    do i=1,11
        Write (*,*) 'cl = ', cl(i)
    end do

    end program Non_Linear_Lifting_Line
     
    If I write down the array cl(i) to monitor, 3 first element of array alphai(i) and alphaeff(i) became messy, but didn't happen if I didn't write it down. I am really really confused why writing down an array could change another array element. Really appreciate your help. I have been googling and don't know what to do or even what happen.
     
  7. Dec 29, 2012 #6
    baby steps...baby steps...

    in addition to the editor window with your source code, open another one
    take most of the calculation code out of your program and put it into the extra window
    leave code that writes variable values to standard output ( "(*,*)" )
    start putting code back a few lines at a time (compile and re-run) until the problem re-appears
    get a hint of what might be happening


    ...by the way, I don't think your "rounding to 1 decimal" division is working as you desire...being that " int(*) " is an integer and 10 (as opposed to 10.0) is also an integer, " int(*)/10 " is going to be evaluated as integral division yielding an integer number with zero decimal places, regardless of the variable type on the left side of the equal sign.
     
Know someone interested in this topic? Share this thread via Reddit, Google+, Twitter, or Facebook




Similar Discussions: Array reading error when opening multiple files in Fortran
Loading...