user3076763
user3076763

Reputation: 11

Error: Rank mismatch in array reference and Warning: Real array index

I have wrote 2 programs in Fortran each one used for doing some calculating for some parameters. After I joined both of them, I got some errors. I couldn't realise the reasons of such errors due to my lack experience in Fortran.

Here are the errors;

    CC2=CUBEROOT(NN,wq)
                 1
Warning: Extension: REAL array index at (1)
growthrate_vs_Il2.f90:46.20:

    CC2=CUBEROOT(NN,wq)
                    1
Warning: Extension: REAL array index at (1)
growthrate_vs_Il2.f90:46.16:

    CC2=CUBEROOT(NN,wq)
                1
Error: Rank mismatch in array reference at (1) (2/1)
growthrate_vs_Il2.f90:48.27:

    call fsub(CC2,Delta0,b,z1,z2,z3)
                           1
Warning: Type mismatch in argument 'f1' at (1); passed COMPLEX(4) to COMPLEX(8)

The code:

program main
implicit none
integer::i,j
real*8,dimension(1000)::Il2,Il3,a0,omega,nominator,dominator,ff,lamda,kk,b,c,d
real*8,dimension(1000)::growth_rate,cb1,cb2   
real*8,dimension(1000)::Il,Delta0, Delta1,m,CC,CC2,BB,mm,NN,wq
real*8::sumo,sumo2,a
real*8,parameter::mass_ratio=0.00870
complex*8,dimension(1000)::z1,z2,z3,f1,f2,f3
real*8,dimension(1000)::cuberoot
      Il=0.0
      Il2=0.0
      sumo=0.0
      a=1.0
do i=1,1000

      Il(i)=sumo+0.1

      omega(i) = 2.359*Il(i)
      nominator=2-omega(i)
      dominator=1-omega(i)
      ff(i)=nominator(i)/dominator(i)
      lamda(i)=sqrt(ff(i))
      kk(i)=1/lamda(i)

      Il2(i)=sumo2+0.001
      a0(i) = 0.68*Il2(i)


      b(i)=-(2.0+omega(i))
      cb1(i)=2.0*omega(i)
      cb2(i)=2.0*kk(i)*a0(i)*mass_ratio
      c(i)=(1.0d0+cb1(i)-cb2(i))
      d(i)=-(omega(i)+cc2(i))
      sumo=Il(i)
      sumo2=Il2(i)
end do

      Delta0= (b**2)-(3*a*c)
      Delta1= (2*(b**3))-(9*a*b*c)+(27*(a**2)*d)
      m=(Delta0)**3
      BB=(Delta1)**2
      mm= BB-(4*m)
      CC=sqrt(mm)
      NN=(Delta1+CC)/2
      CC2=CUBEROOT(NN,wq)

call fsub(CC2,Delta0,b,z1,z2,z3)

      print*,'Delta0',Delta0,'Delta1',Delta1,'mm',mm,'CC2',CC2

      print *, "Omega1_square= ",z1
      print *, "Omega2_square= ",z2
      print *, "Omega3_square= ",z3

end program

the subroutine and functions are as following:

subroutine fsub(x,t,s,f1,f2,f3)
implicit none
integer::k
real(kind=8), intent(in),dimension(1000) :: x,t,s
complex(kind=8), intent(out),dimension(1000) :: f1,f2,f3
complex(kind=8),dimension(1000)::z1,z2,z3

    z1=(1,0)
       f1=(-1/3)*(s+(z1*x)+(t/(z1*x)))
    z2=(-0.5,0.866)
       f2=(-1/3)*(s+(z2*x)+(t/(z2*x)))
    z3=(-0.5,-0.866)
       f3=(-1/3)*(s+(z3*x)+(t/(z3*x)))
end subroutine fsub

real (kind=8)   FUNCTION CUBEROOT (XX,cube_root)

  IMPLICIT NONE

  real(kind=8), INTENT(IN),dimension(1000) :: XX
  Real*8,dimension(1000):: log_x
  real(kind=8),Intent(out),dimension(1000) :: cube_root

       log_x=LOG(XX)
       cube_root=EXP(log_x/3.0)

  RETURN
END FUNCTION CUBEROOT

Upvotes: 0

Views: 1818

Answers (1)

Just a collection of the points immediately leading to the compiler reported errors. I am not saying that after fixing these the program will compile or run correctly.

  1. kind=8 and *8 is not the same. You are lucky they give the same thing for the real type for this compiler, but they don't for the complex type. Please note that complex*8 is single precision and complex(kind=8) is double precision in your compiler.

But also note that the *8 notation for other types than character is not Fortran. It is not and has never been part of any Fortran standard.

  1. In the main code you define the function cuberoot as

    real*8,dimension(1000)::cuberoot
    

First, your function does not return an array (but perhaps it should), so it is wrong. Second, array returning functions cannot be declared in this way anyway. Place your procedures into a module instead of declaring the type as above.

  1. Your function CUBEROOT is wrong. It does not return anything. Perhaps you wanted something like

     FUNCTION CUBEROOT (XX)
       real(kind=something_better_than_8),dimension(1000) :: CUBEROOT
       real(kind=something_better_than_8), INTENT(IN),dimension(1000) :: XX
    
       cuberoot = EXP(LOG(XX)/3) !or just XX**(-1._something_better_than_8/3) if that is what you wanted
     END FUNCTION CUBEROOT
    

It MUST be placed in a module which contains implicit none.

Upvotes: 1

Related Questions