Hello All,
I am trying to perform a 4th order Runge-Kutta integration of
two coupled complex-valued differential equations in Fortran 90
using the gcc compiler. Following are what I think the relevant
snippets of my code:
!!!!! RK4 integration using functions fb and fe which are defined
later. The increment is over an index k. The increment is from
k to k+2 because of the way the system is constructed and is not
important for this question.
do k=1,994,2
k1b(k) = dz1*fb(f1(k))
k1e(k) = dz1*fe(f2(k))
k2b(k) = dz1*fb(f1(k)+k1b(k)/2.0)
k2e(k) = dz1*fe(f2(k)+k1e(k)/2.0)
k3b(k) = dz1*fb(f1(k)+k2b(k)/2.0)
k3e(k) = dz1*fe(f2(k)+k2e(k)/2.0)
k4b(k) = dz1*fb(f1(k)+k3b(k))
k4e(k) = dz1*fe(f2(k)+k3e(k))
f2(k+2) = f2(k)+(1.0/6.0)*(k1b(k)+2*(k2b(k)+k3b(k))+k4b(k))
f1(k+2) = f1(k)+(1.0/6.0)*(k1e(k)+2*(k2e(k)+k3e(k))+k4e(k))
end do
!!!!! The external functions 1are given below. array1 and array2 are globally defined arrays. constant is a globally defined real number.
complex(8) function fb(f1)
complex(8) :: ij = (0,1)
complex(8),intent(in) :: f1
fb = (ij*constant-array1)*f1/(array2)**2
Hello All,
I am trying to perform a 4th order Runge-Kutta integration of two coupled complex-valued differential equations in Fortran 90 using the gcc compiler. Following are what I think the relevant snippets of my code:
!!!!! RK4 integration using functions fb and fe which are defined later. The increment is over an index k. The increment is from k to k+2 because of the way the system is constructed and is not important for this question.
do k=1,994,2
k1b(k) = dz1*fb(f1(k))
k1e(k) = dz1*fe(f2(k))
k2b(k) = dz1*fb(f1(k)+k1b(k)/2.0)
k2e(k) = dz1*fe(f2(k)+k1e(k)/2.0)
k3b(k) = dz1*fb(f1(k)+k2b(k)/2.0)
k3e(k) = dz1*fe(f2(k)+k2e(k)/2.0)
k4b(k) = dz1*fb(f1(k)+k3b(k))
k4e(k) = dz1*fe(f2(k)+k3e(k))
f2(k+2) = f2(k)+(1.0/6.0)*(k1b(k)+2*(k2b(k)+k3b(k))+k4b(k))
f1(k+2) = f1(k)+(1.0/6.0)*(k1e(k)+2*(k2e(k)+k3e(k))+k4e(k))
end do
!!!!! The external functions 1are given below. array1 and array2 are globally defined arrays. constant is a globally defined real number.
complex(8) function fb(f1)
complex(8) :: ij = (0,1)
complex(8),intent(in) :: f1
fb = (ij*constant-array1)*f1/(array2)**2
end function fb
complex(8) function fe(f2)
complex(8) :: ij = (0,1)
complex(8),intent(in) :: f2
fe = (ij*constant)*f2
end function fe
The given code compiles but doesn't increment the functions of interest (f1 and f2). The first value itself (k=1) is nonsensical and thereafter I get NaNs. The initial values given to them are sensible.
I suspect this is because f1 and f2 are arrays and so they need to be defined as such inside the external functions fe and fb.
However, when I do so, gcc gives me an incompatible rank error between fe and f2, since I defined both fe and fb as complex scalars.
But when I define fe and fb as complex arrays,
So I need help in marrying these two issues: to get fe and fb to read f1 and f2 as arrays without being arrays themselves.
You left out some all-important details, i.e. the declaration ofHere are the declarations:
your variables and functions. Without these, it is only possible
to give some general advice. If you have not declared them,
the type inferred from Fortran's implicit type rules is almost
certainly wrong.
The best way is to put your functions fb and fe into a module,Thank you. I will try out this approach.
like this:
module x
implicit none
integer, parameter :: wp = selected_real_kind(15) ! double precision contains
complex (kind=wp) function fb(f1)
fb = ...
end function fb
complex (kind=wp) function fe(f2)
fe = ...
end function fe
end module x
How did you globally define an array? Put it in a module?array1 and array2 have been computed earlier in the main code. Currently there are no modules being used.
You have to know what you want to write.The way I have written the code right now, I want to return a scalar. I would prefer it to be an array as I would be able to keep store all values of k1b,k1e,etc. The problem is, when I tried to define fb and fe as arrays as I mentioned in my original
Is fb an array-valued function or not? Assigning
fb = (ij*constant-array1)*f1/(array2)**2
if array1 and array2 gives you an array, which you cannot assign
to a scalar function. Do you want to return a scalar or
an array?
The way I have written the code right now, I want to return a scalar. I would prefer it to be an array as I would be able to keep store all values of k1b,k1e,etc. The problem is, when I tried to define fb and fe as arrays as I mentioned in my original post, I wasn't able to continue as the arguments of fb
if array1 and array2 gives you an array, which you cannot assign
to a scalar function. Do you want to return a scalar or
an array?
and fe become complex numbers during the k computations inside the loop.
You left out some all-important details, i.e. the declaration ofHere are the declarations:
your variables and functions. Without these, it is only possible
to give some general advice. If you have not declared them,
the type inferred from Fortran's implicit type rules is almost
certainly wrong.
real(8) :: constant
complex(8),dimension(996) :: cEx2,cBy2,k1b,k1e,k2b,k2e,k3b,k3e,k4b,k4e complex(8) :: fb,fe
real(8),parameter :: dz1=4.0E4
The best way is to put your functions fb and fe into a module,Thank you. I will try out this approach.
like this:
module x
implicit none
integer, parameter :: wp = selected_real_kind(15) ! double precision
contains
complex (kind=wp) function fb(f1)
fb = ...
end function fb
complex (kind=wp) function fe(f2)
fe = ...
end function fe
end module x
How did you globally define an array? Put it in a module?array1 and array2 have been computed earlier in the main
code. Currently there are no modules being used.
Would you really want to do in your computation is quite unclear, but I
feel that you need to modify fb() to pass the proper elements of array1
and array2 :
====================================
complex(8) function fb(f1,v1,v2)
complex(8) :: ij = (0,1)
complex(8),intent(in) :: f1
complex(8),intent(in) :: v1, v2
fb = (ij*constant-v1)*f1/(v2)**2
end function fb
====================================
And the calls to fb() would be something like (3 arguments) :
k1b(k) = dz1*fb(f1(k),array1(k),array2(k))
etc. The f functions given there are defined as fb and fe in my case. It is a fairly standard way of solving ordinary differential equations so I think I am making a stupid error somewhere.Would you really want to do in your computation is quite unclear, but I feel that you need to modify fb() to pass the proper elements of array1 and array2 :
====================================
complex(8) function fb(f1,v1,v2)
complex(8) :: ij = (0,1)
complex(8),intent(in) :: f1
complex(8),intent(in) :: v1, v2
fb = (ij*constant-v1)*f1/(v2)**2
end function fb
====================================
And the calls to fb() would be something like (3 arguments) :
k1b(k) = dz1*fb(f1(k),array1(k),array2(k))Thank you. I realised the silly mistake of not declaring the input of v1 and v2 inside my function. The code compiles now. However, the values of the k1b,k1e,k2b, etc. are not getting incremented over the k loop.
I am trying to integrate a set of coupled differential equations using the 4th order Runge-Kutta method (https://en.wikipedia.org/wiki/Runge%E2%80%93Kutta_methods#The_Runge%E2%80%93Kutta_method). In that link, the k1,k2,k3,k4 you see are my k1b,k2b,
I am trying to perform a 4th order Runge-Kutta integration of two coupled complex-valued differential equations in Fortran 90 using the gcc compiler. Following are what I think the relevant snippets of my code:
!!!!! RK4 integration using functions fb and fe which are defined later. The increment is over an index k. The increment is from k to k+2 because of the way the system is constructed and is not important for this question.
!!!!! The external functions 1are given below. array1 and array2 are globally defined arrays. constant is a globally defined real number.
complex(8) function fb(f1)
complex(8) :: ij = (0,1)
complex(8),intent(in) :: f1
fb = (ij*constant-array1)*f1/(array2)**2
end function fb
The given code compiles but doesn't increment the functions of interest (f1 and f2).
The first value itself (k=1) is nonsensical and thereafter I get NaNs. The initial values given to them are sensible.
I suspect this is because f1 and f2 are arrays and so they need to be defined as such inside the external functions fe and fb. However, when I do so, gcc gives me an incompatible rank error between fe and f2, since I defined both fe and fb as complexscalars.
But when I define fe and fb as complex arrays, gcc shoots out an error which says that "array index must be of type integer" inside the various k functions, which makes sense.
So I need help in marrying these two issues: to get fe and fb to read
f1 and f2 as arrays without being arrays themselves.
Sysop: | Keyop |
---|---|
Location: | Huddersfield, West Yorkshire, UK |
Users: | 113 |
Nodes: | 8 (1 / 7) |
Uptime: | 166:15:36 |
Calls: | 2,505 |
Calls today: | 2 |
Files: | 8,705 |
Messages: | 1,931,932 |