可分配的未分配错误

时间:2016-11-16 02:19:53

标签: fortran gfortran allocation

我已经定义了一个名为KhonShamOrbitals的新类型,因为它出现在

下面
type KhonShamOrbitals

    integer :: NumUpOrbitals
    integer :: NumDownOrbitals
    real(dp), allocatable,dimension(:,:) :: PhiUp, PhiDown
    real(dp),allocatable,dimension(:) :: EigenEnergiesUp,EigenEnergiesDown

    real(dp),allocatable, dimension(:) :: DensityUp,DensityDown
end type KhonShamOrbitals

然后我在这个地方将其初始化

type(KhonShamOrbitals) :: orbitals
orbitals%NumUpOrbitals = 1
    orbitals%NumDownOrbitals = 1

    allocate(orbitals%PhiUp(orbitals%NumUpOrbitals,100))
    allocate(orbitals%PhiDown(orbitals%NumDownOrbitals,100))
    allocate(orbitals%EigenEnergiesUp(orbitals%NumUpOrbitals))
    allocate(orbitals%EigenEnergiesDown(orbitals%NumDownOrbitals))
    allocate(orbitals%DensityUp(100))
    allocate(orbitals%DensityDown(100))

之后我调用子程序

call ComputeDensity(1, 100, orbitals%PhiUp, orbitals%DensityUp)

然后定义子程序

subroutine ComputeDensity(NumOrbitals, NumPoints, orbitals, Density)
    integer,intent(in) :: NumOrbitals,NumPoints
    real(dp), intent(in) :: orbitals(NumOrbitals,NumPoints)
    real(dp) :: Density(NumPoints)
    real(dp) :: aux(NumPoints)
    integer i
    Density = 0
    do i  = 1, NumOrbitals
        aux  = orbitals(i,:)
        Density = Density + aux**2
    enddo
end subroutine ComputeDensity

问题是我收到此错误

  

Fortran运行时错误:可分配的实际参数' orbitals'没有分配   在运行程序时。

在MacOS X 10.10上使用gfortran 6.0.0编译。 有关为什么会发生这种情况的任何想法?

2 个答案:

答案 0 :(得分:0)

是否在例程中分配数据?是否有意图(外出)或意图(inout)?

传递具有给定形状的数组。假定的形状可以起作用,并且可以节省明确的尺寸传递。

real(dp), intent(in) :: orbitals(:,:)
NumOrbitals = size(orbitals, dim=1)
NumPoints = size(orbitals, dim=2)

chw21建议检查分配状态是首先要检查的。

如需更多帮助,请使用-g -Wall -fcheck=all标记发布编译的完整输出。

答案 1 :(得分:0)

以下构建与GCC 6.2一样好。

我对您的代码进行了一些更改。

首先,您的派生数据类型现在具有allocate和(隐式)deallocate内存的类型绑定过程。

其次,使用假定形状的数组替换显式形状的数组以提高稳健性。请参阅:Fortran subroutine returning wrong values

最后,您可以通过interface重载派生数据类型的名称以获取用户定义的构造函数。

以下代码

module mymod

  use, intrinsic :: ISO_C_binding, only: &
       ip => C_INT, &
       dp => C_DOUBLE

  ! Explicit typing only
  implicit none

  ! Everything is private unless stated otherwise
  private
  public :: ip, dp, KhonShamOrbitals, ComputeDensity

  ! Declare derived data type
  type, public :: KhonShamOrbitals
    ! Type components
    integer(ip)           :: NumUpOrbitals
    integer(ip)           :: NumDownOrbitals
    real(dp), allocatable :: PhiUp(:,:), PhiDown(:,:)
    real(dp), allocatable :: EigenEnergiesUp(:)
    real(dp), allocatable :: EigenEnergiesDown(:)
    real(dp), allocatable :: DensityUp(:),DensityDown(:)
  contains
    ! Type-bound procedures
    procedure :: create
    procedure :: destroy
  end type  KhonShamOrbitals

  ! Set user-defined constructor
  interface  KhonShamOrbitals
     module procedure constructor
  end interface KhonShamOrbitals

contains

  subroutine destroy(self)
    ! Dummy arguments
    class(KhonShamOrbitals), intent(out) :: self

  end subroutine destroy

  subroutine create(self, n, m)
    ! Dummy arguments
    class(KhonShamOrbitals), intent(inout) :: self
    integer(ip),             intent(in)    :: n
    integer(ip),             intent(in)    :: m

    ! Ensure object is usable
    call self%destroy()

    ! Set constants
    self%NumUpOrbitals = n
    self%NumDownOrbitals = m

    ! Allocate memory
    allocate( self%PhiUp(self%NumUpOrbitals, m) )
    allocate( self%PhiDown(self%NumDownOrbitals, m) )
    allocate( self%EigenEnergiesUp(self%NumUpOrbitals) )
    allocate( self%EigenEnergiesDown(self%NumDownOrbitals) )
    allocate( self%DensityUp(m) )
    allocate( self%DensityDown(m) )

  end subroutine create

  function constructor(n, m) result(return_value)
    integer(ip), intent(in) :: n, m
    type(KhonShamOrbitals)  :: return_value

    call return_value%create(n,m)

  end function constructor

  subroutine ComputeDensity(orbitals, Density)
    ! Dummy arguments
    real(dp), intent(in) :: orbitals(:,:)
    real(dp), intent(out):: Density(:)
    ! Local variables
    integer :: i, NumOrbitals, NumPoints

    NumOrbitals = size(orbitals, dim=1)
    NumPoints = size(orbitals, dim=2)
    Density = 0

    block
      real(dp) :: aux(NumPoints)

      do i  = 1, NumOrbitals
         aux  = orbitals(i,:)
         Density = Density + aux**2
      end do

   end block

  end subroutine ComputeDensity

end module mymod

program main

  use, intrinsic :: ISO_Fortran_env, only: &
       stdout => OUTPUT_UNIT, &
       compiler_version, &
       compiler_options

  use mymod

  implicit none

  type(KhonShamOrbitals) :: foo

  ! Initialize with user-defined constructor
  foo = KhonShamOrbitals(1,100)

  associate( &
       a => foo%PhiUp, &
       b => foo%DensityUp )  
    call ComputeDensity(a, b)
  end associate

  write (stdout, '(/4a/)') &
       'This file was compiled using compiler version ', compiler_version(), &
       ' and compiler options ', compiler_options()

end program main

产量

gfortran -Wall -o main.exe mymod.f90 main.f90
./main.exe

This file was compiled using compiler version GCC version 6.2.0 20161027 and compiler options -mtune=generic -march=x86-64 -Wall