Fortran 填充多维数组
我创建了一个派生类型来访问多维数组。我在数组nm中为每个数组关联一个名称 我的问题在于分配内存后如何填充数组值 最初的想法是使用多维数组作为输入。但是,如果我存储两个副本,可能会遇到内存问题,因为阵列可能很大。一个更好的想法可能是沿着第一维度传递一个一维数组,并在第二维度和第三维度的位置上传递一个关于数据应该驻留的规范 如果有人有使用大数据集的经验,我会很重视一些关于如何更好地将数组填充到派生类型的建议Fortran 填充多维数组,fortran,derived-types,Fortran,Derived Types,我创建了一个派生类型来访问多维数组。我在数组nm中为每个数组关联一个名称 我的问题在于分配内存后如何填充数组值 最初的想法是使用多维数组作为输入。但是,如果我存储两个副本,可能会遇到内存问题,因为阵列可能很大。一个更好的想法可能是沿着第一维度传递一个一维数组,并在第二维度和第三维度的位置上传递一个关于数据应该驻留的规范 如果有人有使用大数据集的经验,我会很重视一些关于如何更好地将数组填充到派生类型的建议 Type :: Multia Character (Len=65) :: nm(3)
Type :: Multia
Character (Len=65) :: nm(3)
Real, Allocatable :: ma(:,:,:)
Real, Allocatable :: mb(:,:,:)
Real, Allocatable :: mc(:,:,:)
Contains
Procedure :: set
End Type Multia
Subroutine set (m, nm, u, i, j)
Class (Multia), Intent (InOut) :: m
Character (Len=65) :: nm
Real, Intent (In) :: u(:)
Integer, Intent (In) :: i, j
If (nm .e. (m% nm(1))) Then
m% ma(:,i,j) = u
Else If (nm .e. (m% nm(2))) Then
m% mb(:,i,j) = u
Else If (nm .e. (m% nm(3))) Then
m% mc(:,i,j) = u
End If
End Subroutine set
如果您担心的是阵列的重复,例如
m%ma = [...] ! Humongous array
然后Fortran 2003提供了move_alloc
内在函数,它将分配(包括值)从一个变量移动到另一个变量
Subroutine set (m, u, v, w)
Class (Multia), Intent (InOut) :: m
Real, Intent (InOut), allocatable, dimension(:,:,:) :: u, v, w
call move_alloc(u, m%ma)
call move_alloc(v, m%mb)
call move_alloc(w, m%mc)
End Subroutine set
叫什么来着
type(Multia) m
real, dimension(:,:,:), allocatable :: u, v, w
! ... allocating and setting u, v, w
call m%set(u, v, w)
! Components of m now allocated, u, v, w, not allocated
从该文件的注释(Fortran 2008)中:
预期可分配对象的实现通常将涉及描述符来定位所分配的存储器;然后可以通过传输描述符的内容来实现MOVE-ALLOC
for FROM到to的描述符,并清除for FROM的描述符
也就是说,预期不会复制数据或数组临时值
当然,这假设您不能只分配
m
的组件并直接分配到那里。您没有给出如何分配组件,但您是否考虑过move\u alloc
?我使用正常分配(m%ma(la,lb,lc))。我不知道有什么动静。我想知道解除分配是如何执行的。我将通过从文件中读取数据来填充数组,然后将值移动到Multia中的一个数组中。是的,我担心的是阵列的重复,这样我就不会出现没有足够的物理RAM来存储这两个阵列的情况。考虑到这一点,还要考虑到实际分配和复制的低效使用。您必须至少进行一次分配(我假设您有某种形式的动态内存使用),但是move\u alloc
应该避免复制和复制,与从文件读取相比,分配将非常便宜。您可以直接从文件读取到Multia
类型的组件中,但这是一种设计选择:希望这里的方法能让您选择是否有一个不同的数组用于某种形式的封装。也许还值得补充的是,这种方法意味着不需要为派生类型的组件进行初始/不同的分配。即使它们最初被分配,它们也会在分配移动之前被解除分配。