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)
读取一次并访问多次的数据非常常见。这是一个简单的例子,说明它是如何工作的。该模块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)
编辑:这里发生了什么的一个关键部分是,x和i被存储在由读取模块和主程序都可以访问的地方。在这个简单的例子中,我选择将它存储在 中my_data,但可以想象它可以在其他地方。您发布的示例代码已被删除(请将其编辑到您的问题中),从不存储您已阅读的数据。读取一次后存储数据是必不可少的。
编辑 2:在您编辑的源代码中,您将数据读DataCube入主程序中声明的变量中。然后,您尝试访问DataCube在子例程中声明的变量中的数据subrtn1。这些不是同一个变量。您必须声明一次,并从多个地方访问它。最好的方法是将它包含在一个模块中,正如我在我的示例中展示的那样。但是,您也可以将其作为参数传递给例程,但这会变得很麻烦。