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

Fortran Using 2D array in dat file

  1. Mar 4, 2016 #1
    Hello everybody,

    I have a source code which gives me as a result an array of 2 columns and 3001 rows (2d array). By using fortran90.

    I was trying to have the values inside these cells in to .dat file and tried to generate a subroutine and call my main array inside this. But somehow I get errors. Linking the code below any help is appreciated.

    Code (Fortran):

    program hw1

    REAL G, Ks, DVIS, EPS,LENGTH,D,Vs,Re,Vi,V0,FFACT,DELt,I,Vi1,J
    INTEGER H, T, PHO
    real, dimension(3001,2):: VTARR
    G=9.81
    D=0.3
    H=8
    ks=0.0001
    T=60
    DVIS=0.001
    PHO=1000
    EPS=0.01
    DELt=0.02
    WRITE (*,*) 'INPUT CYLINDER DIAMETER D:'
    READ (*,*) D
    WRITE (*,*)'INPUT PIPE LENGTH L'
    READ (*,*) LENGTH

        IF (LENGTH==50) THEN
            Vs=6.586        !10.2655
        ELSE IF (LENGTH==100) THEN
            Vs=5.00
        ELSE IF (LENGTH==200) THEN
            Vs=3.669
        ELSE IF (LENGTH==500) THEN
            Vs=2.36
        end if

        Re=PHO*Vs*D/DVIS
        FFACT=0.25/((log10((ks/(3.7*D))+(5.74/Re**0.9)))**2)
        J=1
        do I=0.02,60,0.02
            IF (I==0.02) THEN
            V0=0
            Vi=DELt*H*G/LENGTH
            VTARR(J,1)=Vi
            VTARR(J,2)=I
            J=J+1
            WRITE (*,*) Vi
            ELSE IF (I/=0.02) THEN
            !Re=PHO*Vi*D/DVIS
            !FFACT=0.25/(log((ks/(3.7*D))+(5.74/Re**0.9)))**2
            Vi1=Vi+(DELt*(H-((1+(FFACT*LENGTH/D))*((Vi**2)/(2*G))))*G/LENGTH)
            Vi=Vi1
            VTARR(J,1)=Vi
            VTARR(J,2)=I
            J=J+1
            END IF
            WRITE (*,*) Vi
        end do
        CALL outputdata(VTARR)
    PAUSE
        END PROGRAM

    SUBROUTINE outputdata(X)
      implicit none

    REAL,DOUBLE PRECISION, INTENT(IN) :: X(:,:)

       integer :: i
     
       ! output data into a file
       open(1, file='data1.dat', status='new')
       do i=1,ubound(X,1)
          write(1,*) x(1,i), X(2,i)
       end do
       close(1)

       ! opening the file for reading
       open (2, file='data1.dat', status='old')

    end
     
    <<Moderator's note: code tags added. Next time, you must do that yourself, otherwise your post may be deleted.>>
     
  2. jcsd
  3. Mar 4, 2016 #2

    DrClaude

    User Avatar

    Staff: Mentor

    We are not psychics. If you do not tell us what the errors are, we can't help you.
     
  4. Mar 4, 2016 #3
    Oh yes Ofcourse. I get this error now:

    C:\Users\hasan.dalgic\Documents\Visual Studio 2012\Projects\Console2\Console2\hw1.f90(52): error #7978: Required interface for passing assumed shape array is missing from original source. [VTARR]
     
  5. Mar 4, 2016 #4

    DrClaude

    User Avatar

    Staff: Mentor

    You can't pass array X to the subroutine without either passing its size or making an interface for the subroutine:

    Code (Fortran):

    program hw1

      interface
         subroutine outputdata(x)
            real (kind(1.d0)), intent(in) :: x(:,:)
         end subroutine outputdata
      end interface
     
    Note that you cannot use DOUBLE PRECISION as you did. Also, J should be an integer, as wll as I (you should not have a do loop with a non-integer variable).
     
  6. Mar 4, 2016 #5
    Now I modified my code as it is below. But still I get the error:

    - A specification statement cannot appear in the executable section.

    Code (Fortran):
    program hw1
     
    REAL G, Ks, DVIS, EPS,LENGTH,D,Vs,Re,Vi,V0,FFACT,DELt,I,Vi1,J
    INTEGER H, T, PHO
    real, dimension(3001,2):: VTARR
    G=9.81
    D=0.3
    H=8
    ks=0.0001
    T=60
    DVIS=0.001
    PHO=1000
    EPS=0.01
    DELt=0.02
    WRITE (*,*) 'INPUT CYLINDER DIAMETER D:'
    READ (*,*) D
    WRITE (*,*)'INPUT PIPE LENGTH L'
    READ (*,*) LENGTH
       
        IF (LENGTH==50) THEN
            Vs=6.586        !10.2655
        ELSE IF (LENGTH==100) THEN
            Vs=5.00
        ELSE IF (LENGTH==200) THEN
            Vs=3.669
        ELSE IF (LENGTH==500) THEN
            Vs=2.36
        end if
       
        Re=PHO*Vs*D/DVIS
        FFACT=0.25/((log10((ks/(3.7*D))+(5.74/Re**0.9)))**2)
        J=1
        do I=1,3000,1
            IF (I==0.02) THEN
            V0=0
            Vi=DELt*H*G/LENGTH
            VTARR(J,1)=Vi
            VTARR(J,2)=I
            J=J+1
            WRITE (*,*) Vi
            ELSE IF (I/=0.02) THEN
            !Re=PHO*Vi*D/DVIS
            !FFACT=0.25/(log((ks/(3.7*D))+(5.74/Re**0.9)))**2  
            Vi1=Vi+(DELt*(H-((1+(FFACT*LENGTH/D))*((Vi**2)/(2*G))))*G/LENGTH)
            Vi=Vi1
            VTARR(J,1)=Vi
            VTARR(J,2)=I
            J=J+1
            END IF
            WRITE (*,*) Vi
        end do
       
    PAUSE
    INTERFACE
        SUBROUTINE outputdata(VTARR)
            real (kind(1.d0)), intent(in) :: VTARR(3000,2)
        END SUBROUTINE outputdata
        END INTERFACE
        END PROGRAM
       
     
    SUBROUTINE outputdata(X)  
      implicit none  

    REAL, INTENT(IN) :: X(:,:)
      INTEGER I  
       ! output data into a file
       open(1, file='data1.dat', status='new')
       do I=1,ubound(X,1)
          write(1,*) x(1,I), X(2,I)  
       end do
       close(1)
       ! opening the file for reading
       open (2, file='data1.dat', status='old')
     
    end SUBROUTINE
     
  7. Mar 4, 2016 #6

    DrClaude

    User Avatar

    Staff: Mentor

    The interface has to appear right after the program statement, like in the example I posted.
     
  8. Mar 4, 2016 #7
    But I find my value to be used inside subroutine at the end of the program. And it will be my variable in subroutine. By the way can I assign ubound(array) in to integer variable? I tried it but it was a failure aswell. I am a VBA user and this language is a bit unusual for me.
     
  9. Mar 4, 2016 #8

    DrClaude

    User Avatar

    Staff: Mentor

    It should work:
    Code (Fortran):

     integer :: i,imax
      ! output data into a file
      open(1, file='data1.dat', status='new')
       
      imax = ubound(X,1)

      do i=1,imax
      write(1,*) x(1,i), X(2,i)
      end do
      close(1)
     
     
  10. Mar 4, 2016 #9
    Now the problem is what I get as a result of my main program is VTARR(3001,2) named and dimensioned array.
    How can I write a subroutine or a function that sends the values inside this array in to .dat file?

    Something similar to this but it won' t work as a separated subroutine or function:
    Code (Fortran):
    imax=UBOUND(VTARR,1)
    PAUSE
    I=0
      open(1, file='data1.dat', status='new')
       do I=1,imax,1
          write(1,*) VTARR(I,1), VTARR(I,2)  
       end do
       close(1)
       ! opening the file for reading
       open (2, file='data1.dat', status='old')
     
  11. Mar 4, 2016 #10

    DrClaude

    User Avatar

    Staff: Mentor

    I don't understand. What you wrote should work. Can you explain better how what you want should be different from that?
     
  12. Mar 4, 2016 #11
    Yes it works inside my main program when I write it. But I want to write it outside my main code and use it as a function.

    So that I can send various arrays in to this function and get the .dat files from each of them.

    NOT RELATED TO THİS TOPİC: By the way how can I add "," as a string in between my write(1,*) VTARR(I,1), VTARR(I,2) in order to have format required by datplot program. I need "," in between 2 columns of this array also.
     
  13. Mar 4, 2016 #12

    jtbell

    User Avatar

    Staff: Mentor

    Code (Fortran):

    write (1,*) VTARR(I,1), ',', VTARR(I,2)
     
    By the way, you're asking for trouble by using plain 'I' as a variable name. In some fonts, it's very difficult to see typographical errors involving 'I', '1' and 'l'. :mad:

    (also 'O' and '0')
     
Know someone interested in this topic? Share this thread via Reddit, Google+, Twitter, or Facebook

Have something to add?
Draft saved Draft deleted