Fortran 模块和全局变量

jke*_*ond 4 variables fortran module global

我正在尝试创建一个可供主程序和所有子程序全局访问的数据结构。数据结构是通过读取一些 .dat 文件构建的。

这种全局可访问性似乎适合模块。到目前为止,我的模块解决方案包括:1)全局定义数据类型;2)在模块中包含(包含)一堆子程序来打开/读取.dat文件;和 3) 从 .dat 文件构造数据类型。

理想情况下,我想在模块中一次性构建这个数据结构,然后让这个单一的数据结构全局访问。我不想每次调用模块过程时都打开/读取 .dat 文件。

例如。有没有办法从主程序中将数据结构声明为全局变量,然后调用模块过程来构建数据结构一次?

@罗斯。源代码:

module DataTypeModule

  implicit none

  type :: DatCube
      integer :: NGrid(4)
      double precision, allocatable :: tgrid(:)
  end type DatCube

  contains

  subroutine DataArraySizes(NGrd)
    implicit none
    integer, intent(out) :: NGrd(4)
    open(unit=15, file='./Data/DataHeader.txt', status='old')
    read(15,*) NGrd(1)
    read(15,*) NGrd(2)
    read(15,*) NGrd(3)
    read(15,*) NGrd(4)
    close(15)
  end subroutine DataArraySizes

  subroutine DataTGrd(NGrd,tgrd)
    implicit none
    integer, intent(in) :: NGrd(4)
    double precision, intent(out) :: tgrd(NGrd(1))
    open(unit=16, file='./Data/tgrid.dat', status='old')
    read(16,*) tgrd
    close(16)
  end subroutine DataTGrd

  subroutine ConstructDataCube(DataCube)
    implicit none
    type(DatCube), Intent(out) :: DataCube

    integer, allocatable :: NGrd(:)
    double precision, allocatable :: tgrd(:)

    allocate( NGrd(4) )
    call DataArraySizes(NGrd)
    DataCube%NGrid = NGrd

    allocate( tgrd(NGrd(1)),DataCube%tgrid(NGrd(1)) )
    call DataTGrd(NGrd,tgrd)
    DataCube%tgrid = tgrd

    deallocate( NGrd,tgrd )

    return
  end

end module DataTypeModule

program main
  use DatatypeModule
  implicit none
  double precision :: arg1,out1(4)
  type(DatCube) :: DataCube

  call ConstructDataCube(DataCube)

  call subrtn1(arg1,out1)

  stop
end


subroutine subrtn1(arg1,out1)
  use DataTypeModule
  implicit none
  double precision, Intent(in)  :: arg1
  double precision, Intent(out) :: out1(4)
  type(DatCube) :: DataCube

  out1 = DataCube%NGrid

  return
end
Run Code Online (Sandbox Code Playgroud)

Ros*_*oss 6

读取一次并访问多次的数据非常常见。这是一个简单的例子,说明它是如何工作的。该模块my_data包含要存储的数据x,i和从磁盘读取该数据的子程序read_data。读取应该被调用一次,并且可以从主程序和子程序中多次访问数据。在源文件中main.f90

module my_data
   implicit none

   real :: x
   integer :: i

contains
subroutine read_data
   integer :: fid

   open(newunit=fid,file='config.txt',action='read',position='rewind')

   read(fid,*) x
   read(fid,*) i

   close(fid)
end subroutine read_data
end module my_data

module routines
   implicit none

contains
subroutine mysub
   use my_data, only : x, i

   ! -- Use data again
   write(*,*) 'x and i in subroutine are: ', x, i

end subroutine mysub
end module routines

program main
   use my_data, only : read_data, x, i
   use routines, only : mysub
   implicit none

   ! -- Initialize
   call read_data

   ! -- Use data
   write(*,*) 'x and i in main are: ', x, i

   ! -- Use data in subroutine
   call mysub

end program main
Run Code Online (Sandbox Code Playgroud)

该文件config.txt包含要读取的数据。

mach5% more config.txt
1.23
5
mach5% ifort main.f90 && ./a.out
 x and i in main are:    1.230000               5
 x and i in subroutine are:    1.230000               5
Run Code Online (Sandbox Code Playgroud)

编辑:这里发生了什么的一个关键部分是,xi存储在由读取模块和主程序都可以访问的地方。在这个简单的例子中,我选择将它存储在 中my_data,但可以想象它可以在其他地方。您发布的示例代码已被删除(请将其编辑到您的问题中),从不存储您已阅读的数据。读取一次后存储数据是必不可少的。

编辑 2:在您编辑的源代码中,您将数据读DataCube入主程序中声明的变量中。然后,您尝试访问DataCube在子例程中声明的变量中的数据subrtn1这些不是同一个变量。您必须声明一次,并从多个地方访问它。最好的方法是将它包含在一个模块中,正如我在我的示例中展示的那样。但是,您也可以将其作为参数传递给例程,但这会变得很麻烦。

  • 请耐心等待。我是堆栈交换和 FORTRAN 编程的新手。 (2认同)