Having problem to understand kind notation in fortran 90

• Fortran
• s_hy
In summary: So, to summarize : "kind" is a good idea, but "kind" is also a mess.Best advice : use KIND=1, KIND=2 or KIND=4, which are "standard" (or as standard as anything gets in Fortran).You might be able to find some pre-processor macros that defined KIND=1, KIND=2, KIND=4 according to your compiler. I don't know of any that do this for "kind=5" or other non-standard "kinds".Or (better) you could write a few lines of code that defined your own "kind" values, and use these. This will make your code more readable, and more portable.The gfort
s_hy
hi all,

i have codes for 1d fdtd maxwell equation. the problem i am facing right now is some error regarding the kind notation.

Code:
!1d fdtd Simulation in free space
subroutine fd1d01(f0,miu,delta,S,E0)
implicit none

real        :: f0
real        :: miu
real        :: delta
real        :: S
real        :: E0
integer     :: iinit
integer     :: ilast
real        :: Ca
real        :: Da
integer (kind = 2)  :: i
integer (kind = 5)  :: n
real        :: tdelta
real        :: c
real,dimension(:,:),allocatable   :: Ez
real,dimension(:,:),allocatable   :: Hy
real, parameter :: pi = 3.14159265
real        :: Cb
real        :: Db
real        :: lambda
real        :: alpha
character(len=20)  ::filename

allocate (Ez(-1:103,-1:503))
allocate (Hy(-1:103,-1:503))

f0 = 1.0
miu = 1.0
delta = 1.0
S = 1.0
E0 = 1.0
iinit = 0
ilast = 100

c = 3.e8
lambda = c/f0
print *,'lambda=',lambda
alpha = 0.04*lambda
print *,'alpha=',alpha
tdelta = 1.0*alpha/(S*c)
print*, 'tdelta=',tdelta

!initialization
do i = iinit,ilast
Ez(iinit+1/2,0) = 0
Hy(iinit+1,0) = 0
end do

Ca = 1.0
Cb = tdelta/(delta*alpha)
Da = 1.0
Db = tdelta/(miu*alpha)

!write (filename, "('ez',I3.3,'.dat')") n
!open (unit=130,file=filename)
do n = 1,500
write (filename, "('ez',I3.3,'.dat')") n
open (unit=130,file=filename)
do i = iinit+1,ilast
Ez(real(i-0.5,n+0.5)) = Ca*(Ez(real(i-0.5,n-0.5))) + Cb*(Hy(i,n)-Hy(i-1,n))
Hy(i,n+1) = Da*(Hy(i,n)) + Db*(Ez(real(i+0.5,n+0.5))-Ez(real(i-0.5,n+0.5)))

Write (130,*) i-0.5, Ez(real (i-0.5,n+0.5))
end do !i

!plane wave source

Ez(1./2+(ilast-iinit)/2,n) = E0*sin (2*pi*f0*n*tdelta)

close (unit=130)

end do !n

end SUBROUTINE fd1d01

the error as below:

Code:
subroutines.f90:15.17:

integer (kind = 5)  :: n
1
Error: Kind 5 not supported for type INTEGER at (1)
subroutines.f90:62.4:

do n = 1,500
1
Error: Symbol 'n' at (1) has no IMPLICIT type
subroutines.f90:76.5:

Ez(1./2+(ilast-iinit)/2,n) = E0*sin (2*pi*f0*n*tdelta)
1
Warning: Extension: REAL array index at (1)
make: *** [subroutines.o] Error 1

can anyone advice me how to solve this problem.

thank you

It seems to me that on the computer you are compiling this code, kind = 5 is not supported for integer types. You are asking the compiler to allocate half the normal size for an integer, but the compiler can't do this.

I would either take the kind part out of this line of code
Code:
integer (kind = 5)  :: n

or change to kind = 2.

Here's a link to some info as pertains to the GNU fortran compiler - http://gcc.gnu.org/onlinedocs/gcc-3.4.6/g77/Kind-Notation.html

hi mark44,

i did change KIND= 2, but some error came out as below:

Code:
subroutines.f90:68.17:

Ez(real(i-0.5,n+0.5)) = Ca*(Ez(real(i-0.5,n-0.5))) + Cb*(Hy(i,n)-Hy(i-1,n))
1
Error: 'kind' argument of 'real' intrinsic at (1) must be INTEGER
subroutines.f90:68.45:

Ez(real(i-0.5,n+0.5)) = Ca*(Ez(real(i-0.5,n-0.5))) + Cb*(Hy(i,n)-Hy(i-1,n))
1
Error: 'kind' argument of 'real' intrinsic at (1) must be INTEGER
subroutines.f90:69.70:

Hy(i,n+1) = Da*(Hy(i,n)) + Db*(Ez(real(i+0.5,n+0.5))-Ez(real(i-0.5,n+0.5)))
1
Error: 'kind' argument of 'real' intrinsic at (1) must be INTEGER
subroutines.f90:71.38:

Write (130,*) i-0.5, Ez(real (i-0.5,n+0.5))
1
Error: 'kind' argument of 'real' intrinsic at (1) must be INTEGER
subroutines.f90:76.5:

Ez(1./2+(ilast-iinit)/2,n) = E0*sin (2*pi*f0*n*tdelta)
1
Warning: Extension: REAL array index at (1)

what is that mean?

thank you

Most or all of your errors seem to be that your array indexes for the Ez array are real, not integer.

I'm not sure what you're trying to do in this line:
Code:
Ez(real(i-0.5,n+0.5))= Ca*(Ez(real(i-0.5,n-0.5))) + Cb*(Hy(i,n)-Hy(i-1,n))
The real intrinsic function converts a single integer to a single-precision floating point number. It takes one argument, not two as you are doing.

Your Ez array is two-dimensional - each index needs to be an integer value, not a floating point value. Why do you have indexes that are obviously fractional?

Notice that all five errors point out problems in how you are indexing your Ez array.

IMO, "kind" is a good idea with a very dumb implementation. The good idea is that you can describe what range of values (for integers) or precision (for reals) your program needs, and the compiler can then select the best way to implement this depending on the hardware (32 or 64 bit systems, etc).

The very dumb implementation is that there is NO standardization of what the different integers that denote "kinds" represent, and sometimes no obvious logic either. For example GNU fortran uses KIND=2 to mean "integers of twice the normal length" (that seem logical enough), but KIND=5 means "half the normal length", and "KIND = 7" means "integers large enough to hold a pointer". Yeah, right, it's obvious to everybody that's what 5 and 7 mean

Even worse, GNU says it might change the definitions the definitions in future, so even old "GNU-compatible" code will break. http://gcc.gnu.org/onlinedocs/gcc-3.4.5/g77/Kind-Notation.html

And other compilers might use KIND=2 to mean "2-byte integers", which are "half the normal length" compared with GNU's interpretation of "twice the normal length".

i have make some change. it's compiled but with some warning

Code:
!1d fdtd Simulation in free space
subroutine fd1d01(f0,miu,delta,S,E0)
implicit none

real                               :: f0
real                               :: miu
real                               :: delta
real                               :: S
real                               :: E0
integer                            :: iinit
integer                            :: ilast
integer                            :: i
integer                            :: n
double precision                   :: Ca
double precision                   :: Da
double precision                   :: tdelta
double precision                   :: c
double precision,allocatable       :: Ez(:,:)
double precision,allocatable       :: Hy(:,:)
real, parameter                    :: pi = 3.14159265
double precision                   :: Cb
double precision                   :: Db
double precision                   :: lambda
double precision                   :: alpha
character(len=20)                  :: filename

allocate (Ez(-0.5:103,-0.5:503))
allocate (Hy(-0.5:103,-0.5:503))

f0 = 1.0
miu = 1.0
delta = 1.0
S = 1.0
E0 = 1.0
iinit = 0
ilast = 100

c = 3.e8
lambda = c/f0
alpha = 0.04*lambda
tdelta = 1.0*alpha/(S*c)

!initialization
Ez = 0
Hy = 0

Ca = 1.0
Cb = tdelta/(delta*alpha)
Da = 1.0
Db = tdelta/(miu*alpha)

do n = 1,500
write (filename, "('ez',I3.3,'.dat')") n
open (unit=130,file=filename)
do i = iinit+1,ilast
Ez(i-1./2,n+1./2) = Ca*(Ez(i-1./2,n-1./2)) + Cb*(Hy(i,n)-Hy(i-1.,n))
Hy(i,n+1.) = Da*(Hy(i,n)) + Db*(Ez(i+1./2,n+1./2)-Ez(i-1./2,n+1./2))
!  Print*, 'i+1./2=',i+1./2,'i-1./2=',i-1./2
Write (130,*) i-1./2, Ez(i-1./2,n+1./2)
end do !i

!plane wave source

Ez(1./2+(ilast-iinit)/2,n) = E0*sin (2*pi*f0*n*tdelta)

close (unit=130)

end do !n

end SUBROUTINE fd1d01

and the warnings are as below:

Code:
gfortran -g  -I/usr/include -c main.f90
gfortran -g  -I/usr/include -c subroutines.f90
subroutines.f90:27.13:

allocate (Ez(-0.5:103,-0.5:503))
1
Warning: Extension: REAL array index at (1)
subroutines.f90:27.22:

allocate (Ez(-0.5:103,-0.5:503))
1
Warning: Extension: REAL array index at (1)
subroutines.f90:28.13:

allocate (Hy(-0.5:103,-0.5:503))
1
Warning: Extension: REAL array index at (1)
subroutines.f90:28.22:

allocate (Hy(-0.5:103,-0.5:503))
1
Warning: Extension: REAL array index at (1)
subroutines.f90:65.6:

Ez(i-1./2,n+1./2) = Ca*(Ez(i-1./2,n-1./2)) + Cb*(Hy(i,n)-Hy(i-1.,n))
1
Warning: Extension: REAL array index at (1)
subroutines.f90:65.13:

Ez(i-1./2,n+1./2) = Ca*(Ez(i-1./2,n-1./2)) + Cb*(Hy(i,n)-Hy(i-1.,n))
1
Warning: Extension: REAL array index at (1)
subroutines.f90:65.63:

Ez(i-1./2,n+1./2) = Ca*(Ez(i-1./2,n-1./2)) + Cb*(Hy(i,n)-Hy(i-1.,n))
1
Warning: Extension: REAL array index at (1)
subroutines.f90:65.30:

Ez(i-1./2,n+1./2) = Ca*(Ez(i-1./2,n-1./2)) + Cb*(Hy(i,n)-Hy(i-1.,n))
1
Warning: Extension: REAL array index at (1)
subroutines.f90:65.37:

Ez(i-1./2,n+1./2) = Ca*(Ez(i-1./2,n-1./2)) + Cb*(Hy(i,n)-Hy(i-1.,n))
1
Warning: Extension: REAL array index at (1)
subroutines.f90:66.8:

Hy(i,n+1.) = Da*(Hy(i,n)) + Db*(Ez(i+1./2,n+1./2)-Ez(i-1./2,n+1./2))
1
Warning: Extension: REAL array index at (1)
subroutines.f90:66.56:

Hy(i,n+1.) = Da*(Hy(i,n)) + Db*(Ez(i+1./2,n+1./2)-Ez(i-1./2,n+1./2))
1
Warning: Extension: REAL array index at (1)
subroutines.f90:66.63:

Hy(i,n+1.) = Da*(Hy(i,n)) + Db*(Ez(i+1./2,n+1./2)-Ez(i-1./2,n+1./2))
1
Warning: Extension: REAL array index at (1)
subroutines.f90:66.38:

Hy(i,n+1.) = Da*(Hy(i,n)) + Db*(Ez(i+1./2,n+1./2)-Ez(i-1./2,n+1./2))
1
Warning: Extension: REAL array index at (1)
subroutines.f90:66.45:

Hy(i,n+1.) = Da*(Hy(i,n)) + Db*(Ez(i+1./2,n+1./2)-Ez(i-1./2,n+1./2))
1
Warning: Extension: REAL array index at (1)
subroutines.f90:70.27:

Write (130,*) i-1./2, Ez(i-1./2,n+1./2)
1
Warning: Extension: REAL array index at (1)
subroutines.f90:70.34:

Write (130,*) i-1./2, Ez(i-1./2,n+1./2)
1
Warning: Extension: REAL array index at (1)
subroutines.f90:75.5:

Ez(1./2+(ilast-iinit)/2,n) = E0*sin (2*pi*f0*n*tdelta)
1
Warning: Extension: REAL array index at (1)
gfortran -g  -I/usr/include -o main main.o subroutines.o -L/usr/lib64/liblapack -L/usr/lib64/libblas
Main finished.

can u guys explain why i get this warning?

thank you

This is what I said a couple of posts back (emphasis added). Did you read it?
Mark44 said:
Your Ez array is two-dimensional - each index needs to be an integer value, not a floating point value. Why do you have indexes that are obviously fractional?
Notice that all five errors point out problems in how you are indexing your Ez array.

mark 44,

i read your reply, and i make change...but somehow it came out with lib64 error and so on.

maybe i misunderstood, ( my english is freaking bad, and fortran for me is just a few months experience)...i've change this part

allocate (Ez(-0.5:103,-0.5:503))
allocate (Hy(-0.5:103,-0.5:503))

into

allocate (Ez(-2:100,0:501))
allocate (Hy(-2:100,0:501))

or

allocate (Ez(0:100,0:500))
allocate (Hy(0:100,0:500))

and then this error came out:

*** glibc detected *** ./main: free(): invalid pointer: 0x00007fdb92dbf010 ***

and so on.

or is it the warning came out because of this algorithm

Ez(i-1./2,n+1./2) = Ca*(Ez(i-1./2,n-1./2)) + Cb*(Hy(i,n)-Hy(i-1.,n))

i just translate the finite difference expression for maxwell equations from taflove's book into fortran language.

please highlight me...which part i should change.

and very big thank you for your time

s_hy said:
mark 44,

i read your reply, and i make change...but somehow it came out with lib64 error and so on.

maybe i misunderstood, ( my english is freaking bad, and fortran for me is just a few months experience)...i've change this part

allocate (Ez(-0.5:103,-0.5:503))
allocate (Hy(-0.5:103,-0.5:503))

into

allocate (Ez(-2:100,0:501))
allocate (Hy(-2:100,0:501))

or

allocate (Ez(0:100,0:500))
allocate (Hy(0:100,0:500))

and then this error came out:

*** glibc detected *** ./main: free(): invalid pointer: 0x00007fdb92dbf010 ***
I don't have much recent experience with fortran, but I suspect that this error is cause by not deallocating the memory that you allocated. Also, I don't believe that your allocate statements are right. They should just indicate how many cells in each dimension to allocate.

I might be wrong, but I think the above statements should be something like this:
Code:
allocate(Ez(101, 501), STAT =  status)
and similar for your Hy array.

s_hy said:
and so on.

or is it the warning came out because of this algorithm

Ez(i-1./2,n+1./2) = Ca*(Ez(i-1./2,n-1./2)) + Cb*(Hy(i,n)-Hy(i-1.,n))
This is what I've been saying. You can't do this!
Ez(i-1./2,n+1./2) = Ca*(Ez(i-1./2,n-1./2)) + Cb*(Hy(i,n)-Hy(i-1.,n))

The indexes in an array have to be integer numbers. You can't access the element whose index is 3.5, for example.

You have to change your code so that you store values at integer indexes in the arrays.
s_hy said:
i just translate the finite difference expression for maxwell equations from taflove's book into fortran language.

please highlight me...which part i should change.

and very big thank you for your time

Last edited:

1. What is kind notation in Fortran 90?

Kind notation in Fortran 90 is a way to specify the precision and range of numeric data types. It allows you to define variables with a specific number of digits, which can be useful for scientific calculations where precision is important.

2. How is kind notation used in Fortran 90?

In Fortran 90, kind notation is typically used in the declaration of variables, where you specify the desired kind of the variable using the KIND keyword. For example, REAL(KIND=8) :: x declares a real variable x with 8 digits of precision.

3. What are the different kinds available in Fortran 90?

Fortran 90 offers a variety of kinds for different data types, such as INTEGER, REAL, and COMPLEX. The available kinds vary depending on the compiler and system, but some common kinds are KIND=4 for single precision, KIND=8 for double precision, and KIND=16 for quadruple precision.

4. How do I determine the appropriate kind for my variables?

The appropriate kind for your variables depends on the precision and range required for your calculations. It is important to consider the limitations of your system and the accuracy needed for your results. You can consult the documentation for your compiler or consult with other Fortran programmers for guidance.

5. Are there any other uses for kind notation in Fortran 90?

Yes, kind notation can also be used for character variables to specify the length of the string. For example, CHARACTER(KIND=10) :: name declares a character variable name with a length of 10 characters. Kind notation can also be used in certain intrinsic functions, such as KIND() and SELECTED_REAL_KIND(), to determine the appropriate kind for a given data type.

• Programming and Computer Science
Replies
1
Views
4K
• Programming and Computer Science
Replies
4
Views
1K
• Programming and Computer Science
Replies
4
Views
3K
• Programming and Computer Science
Replies
5
Views
2K
• Programming and Computer Science
Replies
2
Views
2K
Replies
1
Views
4K
• Programming and Computer Science
Replies
4
Views
2K
• Programming and Computer Science
Replies
4
Views
16K
• Programming and Computer Science
Replies
4
Views
12K
• Programming and Computer Science
Replies
4
Views
3K