我正在读取沿时间轨迹的分子速度。我正在尝试计算v_i(t)* v_j(t + n∆t),其中i和j不一定是同一原子。
我使用嵌套的do循环进行计算,根据定义,该计算适用于不同的时间步长,不同的分子和不同的原子。我有多个嵌套的do循环,这会降低代码速度并导致内存问题。如果可能,我想避免这些问题。如何使用Fortran 90改进代码?
PROGRAM BUILD
IMPLICIT NONE
INTEGER :: I,K,L,L1,L2,M1,M2,T,T1,T2,NCON,NMOL,NSIT,SPLIT,LOOP
REAL(8) :: X,Y,Z,V1,V2,V3,R,TRASH
REAL(8),ALLOCATABLE :: VX(:,:,:),VY(:,:,:),VZ(:,:,:)
REAL(8),ALLOCATABLE :: NORM(:,:,:,:,:),V(:,:,:,:,:)
! Input
NCON = 100001 ! Number of configurations
NMOL = 524 ! Number of molecules
NSIT = 6 ! Number of sites on each molecule
SPLIT = 50 ! Number of subgroups of configurations
LOOP = (NCON-1)/SPLIT ! Number of configurations in each subgroup
! * * * * * * * * *
! Allocate memory
ALLOCATE ( VX(0:LOOP,NMOL,NSIT) )
ALLOCATE ( VY(0:LOOP,NMOL,NSIT) )
ALLOCATE ( VZ(0:LOOP,NMOL,NSIT) )
ALLOCATE ( V(0:LOOP,NMOL,NMOL,NSIT,NSIT) )
ALLOCATE ( NORM(0:LOOP,NMOL,NMOL,NSIT,NSIT) )
ALLOCATE ( VIVJ(0:LOOP,NSIT,NSIT) )
ALLOCATE ( N(0:LOOP,NSIT,NSIT) )
! Initialize
VX = 0.0D0
VY = 0.0D0
VZ = 0.0D0
V = 0.0D0
NORM = 0.0D0
VIVJ = 0.0D0
N = 0.0D0
! Read trajectories
OPEN(UNIT=15,FILE='HISTORY',STATUS='UNKNOWN',ACTION='READ')
DO I = 1,SPLIT
WRITE(*,*) I,SPLIT
DO T = 0,LOOP-1
DO L = 1,NMOL
DO K = 1,NSIT
READ(15,*) V1,V2,V3
VX(T,L,K) = V1
VY(T,L,K) = V2
VZ(T,L,K) = V3
END DO
END DO
END DO
! Calculate functions
DO T1 = 1,LOOP
DO T2 = T1,LOOP
DO L1 = 1,NMOL
DO M1 = 1,NSIT
DO L2 = 1,NMOL
DO M2 = 1,NSIT
! Includes all atoms, both intermolecular and intramolecular
! Keep all of the molecules
V(T2-T1,L1,L2,M1,M2) = V(T2-T1,L1,L2,M1,M2) + &
VX(T1,L1,M1)*VX(T2,L2,M2) + &
VY(T1,L1,M1)*VY(T2,L2,M2) + &
VZ(T1,L1,M1)*VZ(T2,L2,M2)
! Accounting
NORM(T2-T1,L1,L2,M1,M2) = NORM(T2-T1,L1,L2,M1,M2) + 1.0D0
END DO
END DO
END DO
END DO
END DO
END DO
CLOSE(15)
DEALLOCATE(VX)
DEALLOCATE(VY)
DEALLOCATE(VZ)
DEALLOCATE(V)
DEALLOCATE(NORM)
END PROGRAM
答案 0 :(得分:2)
Fortran以不同于C和其他大多数语言的顺序存储数组。
do T = ...
do L = ...
do K = ...
array(T, L, K) = ...
end do
end do
end do
总是会比
慢得多do K = ...
do L = ...
do T = ...
array(T, L, K) = ...
end do
end do
end do
所有其他条件都一样。