fortran - 有什么方法可以避免 Fortran 90 中的嵌套 do 循环?
问题描述
我正在沿时间轨迹读取分子的一些速度。我正在尝试计算 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
解决方案
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
所有其他条件都相同。
推荐阅读
- css - Nuxt 中的条件样式表
- reactjs - React - 使用 JSON 存储数据
- plpgsql - 从客户端,这与 SELECT 完美配合并返回布尔值。但是,作为 Function 它不能作为 plpgsl
- reactjs - 当我使用句柄登录方法时,它会导致“超出最大更新深度”
- ios - iOS SwiftUI:子视图中的数据流流@ObservedObject
- c# - 如何发布到休息 api 并使用 c# 中的非结束流?
- node.js - 如何从 fs.statSync 存根 isFile
- mysql - 为什么在 MySQL 触发器查询中出现语法错误?
- php - 使用 where 子句获取加密数据
- python - 如何使用 Google 的 Universal Sentence Encoder 根据多个文档找到最相似的文档?