Questions related to this one have been posted before, but I could not find a satisfying recommendation for my particular use case. I am looking for some advice about best practices in making code that is readable while also avoiding undesirable effects.
I have a subroutine that operates on a number of components of a derived type. To simplify the argument list, I just pass the complete structure to the subroutine:
subroutine K_unsat(soilstate)
use parametersmod, only : sp
use typesmod, only : soilstatetype
implicit none
! argument
type(soilstatetype), dimension(:), target, intent(inout) :: soilstate
Because I need to update various components of the derived type, and to avoid writing cumbersome code, I experimented with giving the argument the target attribute and creating pointers as shorthand to the components:
! pointers to state variables
real(sp), dimension(:), pointer :: Bexp
real(sp), dimension(:), pointer :: ddKuTliq
real(sp), dimension(:), pointer :: ddPsiTliq
real(sp), dimension(:), pointer :: ffrz
real(sp), dimension(:), pointer :: Ksat
real(sp), dimension(:), pointer :: Ku
real(sp), dimension(:), pointer :: psi_e
real(sp), dimension(:), pointer :: psi
real(sp), dimension(:), pointer :: Sr
real(sp), dimension(:), pointer :: T_wat
real(sp), dimension(:), pointer :: Tice
real(sp), dimension(:), pointer :: Tliq
real(sp), dimension(:), pointer :: Tsat
Then I assigned these pointers to the respective components of the derived type argument:
! variable and pointer assignment
Bexp => soilstate%Bexp
ddKuTliq => soilstate%ddKuTliq
ddPsiTliq => soilstate%ddPsiTliq
ffrz => soilstate%ffrz
Ksat => soilstate%Ksat
Ku => soilstate%Ku
psi_e => soilstate%psi_e
psi => soilstate%psi
Sr => soilstate%Sr
T_wat => soilstate%T_wat
Tice => soilstate%Tice
Tice => soilstate%Tliq
Tsat => soilstate%Tsat
and then I do my calculations, using the pointers as shorthand to the components, for example (shortened for clarity):
do l = 1,nl
...
psi(l) = psi_e(l) * Sr(l)**(-Bexp(l))
...
ddPsiTliq(l) = -Bexp(l) * psi(l) / (Sr(l) * Tsat(l))
end do
end subroutine K_unsat
My question is, is there a better way to achieve this kind of shorthand to individual structure components? I looked in to an associate block, but that would also lead to a gnarly line of code if I was defining local names to 10+ structure components. Creating new variables in the local context would require a bunch of allocate statements and variable assignments at the beginning and end of the routine, although I suppose that might make the intent of each component more obvious.
Thanks for your advice!