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

  • Context: Fortran 
  • Thread starter Thread starter abdulsulo
  • Start date Start date
  • Tags Tags
    2d Array File
Join the discussion
Ask a follow-up here, or get your own question answered by working scientists, mathematicians and engineers — people, not an autocomplete.
Real named experts · corrections over time · the nuance an AI answer skips
11 replies · 3K views
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.>>
 
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   Reactions: 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')
 
I don't understand. What you wrote should work. Can you explain better how what you want should be different from that?
 
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.
 
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   Reactions: abdulsulo