I have a user type which contains two or more arrays of different sizes.
type state
real(real64) :: pos(3), ori(4), vee(3), omg(3)
end type
and I have defined the (*)
and (+)
operators in order to be able to do algebra
interface operator (+)
procedure st_add
end interface
interface operator (*)
procedure st_scale1, st_scale2
end interface
contains
elemental function st_add(a,b) result(c)
type(state), intent(in) :: a,b
type(state) :: c
c = state( &
a%pos + b%pos, &
a%ori + b%ori, &
a%vee + b%vee, &
a%omg + b%omg)
end function
elemental function st_scale1(a,b) result(c)
real(real64), intent(in) :: a
type(state), intent(in) :: b
type(state) :: c
c = state( &
a * b%pos, &
a * b%ori, &
a * b%vee, &
a * b%omg)
end function
elemental function st_scale2(b,a) result(c)
real(real64), intent(in) :: a
type(state), intent(in) :: b
type(state) :: c
c = state( &
a * b%pos, &
a * b%ori, &
a * b%vee, &
a * b%omg)
end function
now I am using the above in a linear algebra operation such as
real(real64), parameter :: c(4) = [1/6d0, 2/6d0, 2/6d0, 1/6d0]
type(state) :: k(4),k_step
k_step = c(1)*k(1)+c(2)*k(2)+c(3)*k(3)+c(4)*k(4)
but what I want for brevity and code flexibility to use the following
k_step = sum( c(:)*k(:) ) ! error
which results in the following error error #6362: The data types of the argument(s) are invalid. [SUM]
.
So what are my options? Do I need an generic interface for sum
calling st_add
? Or do I need some other definition?
I am using Intel? Fortran Compiler Classic 2021.1.2 (part of oneAPI HPC).
Solution
The solution that worked best is to add the following
interface sum
procedure st_sum
end interface
contains
pure function st_sum(a) result (s)
type(state), intent(in) :: a(:)
type(state) :: s
integer :: i, n
n = size(a)
s = a(1)
do i=2, n
s = s + a(i)
end do
end function
and usage
k_step = sum(c(:)*k(:))
st = this + h*k_step
Well, I actually I combined the two statements above into one
st = this + sum( (h*c(:))*k(:) )
Overall I get the same results, but with a slight performance penalty (about 10%). It must be all that array copying values for function results. IDK.
question from:
https://stackoverflow.com/questions/66065400/making-sum-function-work-with-derived-types