Fortran How to Write a 2D Array to a .dat File in Fortran90?

  • Thread starter Thread starter abdulsulo
  • Start date Start date
  • Tags Tags
    2d Array File
AI Thread Summary
The discussion revolves around a Fortran90 program that generates a 2D array of values and attempts to write these values to a .dat file using a subroutine. The user encounters multiple errors related to passing the array to the subroutine, specifically regarding the required interface for assumed shape arrays and the proper declaration of variables. Key issues highlighted include the need to define an interface for the subroutine to accept the array correctly, as well as ensuring that the loop variables are integers. The user also struggles with the placement of the interface and the correct syntax for writing to the file, including formatting the output to include a comma between columns. Suggestions from other users emphasize the importance of proper variable naming to avoid confusion, and they clarify that the user can indeed assign the upper bound of an array to an integer variable. The user seeks to create a reusable subroutine that can handle different arrays for output, indicating a desire for modularity in their code.
abdulsulo
Messages
13
Reaction score
0
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 into .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.

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.>>
 
Technology news on Phys.org
abdulsulo said:
But somehow I get errors.
We are not psychics. If you do not tell us what the errors are, we can't help you.
 
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]
 
You can't pass array X to the subroutine without either passing its size or making an interface for the subroutine:

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).
 
Now I modified my code as it is below. But still I get the error:

- A specification statement cannot appear in the executable section.

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
 
The interface has to appear right after the program statement, like in the example I posted.
 
  • Like
Likes abdulsulo
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) into 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.
 
It should work:
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)
 
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 into .dat file?

Something similar to this but it won' t work as a separated subroutine or function:
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')
 
  • #10
I don't understand. What you wrote should work. Can you explain better how what you want should be different from that?
 
  • #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 into 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.
 
  • #12
abdulsulo said:
how can I add "," as a string in between my write(1,*) VTARR(I,1), VTARR(I,2)

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')
 
  • Like
Likes abdulsulo

Similar threads

Replies
4
Views
2K
Replies
10
Views
25K
Replies
2
Views
2K
Replies
4
Views
11K
Replies
2
Views
1K
Replies
3
Views
12K
Back
Top