我已经定义了一个名为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编译。 有关为什么会发生这种情况的任何想法?
答案 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