# Avoid temporary arrays when using derived types

Suppose that I have a subroutine that revises arrays `A` and `B` by some intensive computation:

``````subroutine foo(A, B)
real, intent(inout) :: A(:, :), B(:, :)
! Do something intensive to revise A, B
end subroutine foo
``````

Now, I would like to define a derived type `DT` consisting of `A` and `B` and rewrite `foo` into `bar` as follows.

``````subroutine bar(D)
type(DT), intent(inout) :: D
! Do something intensive to revise D%A, D%B
end subroutine bar
``````

Here comes a problem. The calculation that revises `A` and `B` is truly intensive. So it would be cumbersome to write always `D%A` and `D%B`. To solve this problem, we may define temporary arrays `A=D%A` and `B=D%B`, work on `A` and `B`, and then set `D%A=A`, `D%B=B` before the end of the subroutine. However, if `A` and `B` are huge, this would not be ideal. So, what is the best practice in this situation?

3 Likes

Look into `ASSOCIATE` construct:

``````subroutine bar(D)
type(DT), intent(inout) :: D
associate ( A => D%A, B => D%B )
! Do something intensive to revise D%A, D%B via associate-names of A and B!
end associate
end subroutine bar
``````
10 Likes

How does one decide between the solution above and an internal subroutine, as illustrated below? I assume compilers would not make copies of the
`intent(in out)` arguments.

``````subroutine bar(D)
type(DT), intent(inout) :: D
call foo(D%A,D%B)
contains
subroutine foo(A,B)
real, intent(in out) :: A(:,:), B(:,:)
! modify A and B
end suboutine calc
end subroutine bar
``````
2 Likes

I would not even make the subroutine `foo` internal. I like to create such standalone procedures as much as possible that operate on arrays, no derived types. This makes them very reusable in all kinds of settings.

Then in the upper calls if it makes sense to use a derived type, then the member arrays can be passed as arguments as shown above.

4 Likes

Thank @FortranFan, @Beliavsky, and @certik all of you for the illuminating suggestions. I believe that each of them is quite useful under certain situations. I understand this problem better now. Considering my code, I guess I would more or less follow what @certik suggests, namely to implement the true calculations on arrays, and then use derived types only as â€śinterfacesâ€ť between different components of the program.

Many thanks again!

2 Likes