Function 如何在Fortran的不同文件中使用变量?
我有一个Fortran项目的问题,我想也许你能帮我 我使用代码块作为IDE,在那里你可以创建项目,所以我创建了一个项目,其中有两个文件:一个主程序和一个功能,我不知道还能用什么,我可以使用一些不同于功能的东西 所以我有一个函数,它从一个.txt文件中读取值,并将它们保存为实数,一切正常。我想做的是,从文件main调用这个函数,并将我用函数收集的数据保存在main中,以便main保持干净 我该怎么做?如果你愿意,我可以发布整个脚本,但我不认为它会增加那么多 编辑:如您所问,此处未剪切:Function 如何在Fortran的不同文件中使用变量?,function,fortran,main,Function,Fortran,Main,我有一个Fortran项目的问题,我想也许你能帮我 我使用代码块作为IDE,在那里你可以创建项目,所以我创建了一个项目,其中有两个文件:一个主程序和一个功能,我不知道还能用什么,我可以使用一些不同于功能的东西 所以我有一个函数,它从一个.txt文件中读取值,并将它们保存为实数,一切正常。我想做的是,从文件main调用这个函数,并将我用函数收集的数据保存在main中,以便main保持干净 我该怎么做?如果你愿意,我可以发布整个脚本,但我不认为它会增加那么多 编辑:如您所问,此处未剪切: progr
program main
! Variables
real :: d1, r1, r2, a, teta, freq, Dt, mu, g0, r_t, height, r, omega, H, lx, ly, lz, m_c0, &
Jx, Jy, Jz, gmax, I_s, K, Jx0, Jy0, Jz0, Vmin, tsp_0, Fmax, Isp, c1, n, F, DV, tfin, cont, Tmax
real :: data_input
! Call the funcion
data_input=data_module(d1, r1, r2, a, teta, freq, Dt, mu, g0, r_t, height, r, omega, H, lx, ly, lz, m_c0, &
Jx, Jy, Jz, gmax, I_s, K, Jx0, Jy0, Jz0, Vmin, tsp_0, Fmax, Isp, c1, n, F, DV, tfin, cont, Tmax)
! Error
if (data_input/=1) then
print*, 'ERROR: data_module did not work'
end if
!Just to show it
print*,'After'
print*, d1, r1, r2, a, teta, freq, Dt, mu, g0, r_t, height, r, omega, H, lx, ly, lz, m_c0, &
Jx, Jy, Jz, gmax, I_s, K, Jx0, Jy0, Jz0, Vmin, tsp_0, Fmax, Isp, c1, n, F, DV, tfin, cont, Tmax
end program main
real function data_module ()
! Variables
implicit none
integer :: flag_read=0, w_int, d_int
real:: coefficient, d1, r1, r2, a, teta, freq, Dt, mu, g0, r_t, height, r, omega, H, lx, ly, lz, m_c0, &
Jx, Jy, Jz, gmax, I_s, K, Jx0, Jy0, Jz0, Vmin, tsp_0, Fmax, Isp, c1, n, F, DV, tfin, cont, Tmax
character (LEN=35) :: starting_string, name*15, coefficient_string*20, w_string, d_string, number_format
character :: w*2, d
! Open file
open (11, file = 'Data.txt', status = 'old', access = 'sequential', form = 'formatted')
! Read a new line for every iteration
sentence_reader: do while (flag_read==0)
read (11, fmt='(A)', iostat = flag_read) starting_string
! Error
if (flag_read>0)then
print*, 'ERROR: could not read data'
stop
end if
! Skip useless lines
if (starting_string(1:1)=='%' .OR. starting_string(1:1)==' ') then
cycle
end if
! Exit when you're done
if (flag_read<0)then
exit sentence_reader
end if
! Just stuff to prepare it
name=trim(starting_string(1:index(starting_string, '=')-1))
coefficient_string=trim(adjustl(starting_string(index(starting_string, '=')+1:index(starting_string,';')-1)))
if (scan(coefficient_string,'E')/=0) then
w_string=coefficient_string
w_int=len_trim(w_string)
write(w, '(BN,I2)') w_int
d_string=coefficient_string(index(coefficient_string, '.')+1:index(coefficient_string, 'E')-1)
d_int=len_trim(d_string)
write(d, '(BN,I1)') d_int
!All togheter
number_format='(BN,F' // trim(w) // '.' // d // ')'
else
w_string=coefficient_string
w_int=len_trim(w_string)
write(w, '(BN,I1)') w_int
d_string=coefficient_string(index(coefficient_string, '.')+1:len_trim(coefficient_string))
d_int=len_trim(d_string)
write(d, '(BN,I1)') d_int
number_format='(BN,F' // trim(w) // '.' // d // ')'
end if
! Read the number
read(coefficient_string,number_format) coefficient
! Save where it's needed (is there an easier way to do it?)
select case (name)
case ('d1')
d1=coefficient
case ('r1')
r1=coefficient
case ('r2')
r2=coefficient
case ('a')
exit
case ('teta')
exit
case ('freq')
freq=coefficient
case ('Dt')
exit
case ('mu')
mu=coefficient
case ('g0')
g0=coefficient
case ('r_t')
r_t=coefficient
case ('height')
height=coefficient
case ('lx')
lx=coefficient
case ('ly')
ly=coefficient
case ('lz')
lz=coefficient
case ('m_c0')
m_c0=coefficient
case ('Jx')
Jx=coefficient
case ('Jy')
Jy=coefficient
case ('Jz')
Jz=coefficient
case ('gmax')
gmax=coefficient
case ('I_s')
I_s=coefficient
case ('K')
K=coefficient
case ('Vmin')
Vmin=coefficient
case ('tsp_0')
tsp_0=coefficient
case ('Fmax')
Fmax=coefficient
case ('Isp')
Isp=coefficient
case ('n')
n=coefficient
case ('tfin')
tfin=coefficient
case ('cont')
cont=coefficient
case ('Tmax')
Tmax=coefficient
case default
print*, 'Variable ', name, ' is not recognized'
end select
end do sentence_reader
! Other stuff I need
teta=atan((r1 - r2)/d1)
a=sqrt(d1**2 + (r1 - r2)**2)
Dt=1/freq
r=r_t + height
omega=(mu/(r**3))**0.5
H=(r*mu)**0.5
Jx0=Jx - I_s
Jy0=Jy - I_s
Jz0=Jz - I_s
c1=Isp*g0
F=n*Fmax
DV=(F/m_c0)*tsp_0
! Shows that the function is correctly executed
data_module=1
print*,'Before'
print*, d1, r1, r2, a, teta, freq, Dt, mu, g0, r_t, height, r, omega, H, lx, ly, lz, m_c0, &
Jx, Jy, Jz, gmax, I_s, K, Jx0, Jy0, Jz0, Vmin, tsp_0, Fmax, Isp, c1, n, F, DV, tfin, cont, Tmax
end function data_module
顺便说一句,我知道模块,但是有了open和其他东西,我无法让它们工作。我很乐意
我想做的是将我在data_模块中收集的数据d1、r1、ecc传递到main并保存在main中,但这样做不会保存它们,如果您运行它,当您在一切正常之前打印它们,当您在得到所有零之后打印它们。好的,我注意到一些事情 您的函数是real类型的,但您只将其设置为1,即整数,当您将其放在注释中时,将显示该函数已正确执行。 让一个过程返回一个值来显示它是否正确执行并不少见,但它通常是一个错误代码,零意味着没有错误发生,一切正常。 此外,您可能希望将函数声明为整数而不是实数,因为整数更适合这种情况。比较起来更可靠 至于您的实际问题:如果您想将多个值传递回调用例程,那么您需要声明intentout伪变量。请参见此示例:
integer function test_output(outdata)
integer, intent(out) :: outdata(10)
integer :: i
outdata = (/(i, i=1, 10)/)
! All worked well
test_output = 0
return
end function test_output
模块是一条路要走。下面是一个非常有限的示例,说明如何将上述功能合并到模块中,并在程序中使用该模块:
module mod_test
implicit none
! Here you can place variables that should be available
! to any procedure using this module
contains
! Here you can place all the procedures (functions and
! subroutines)
integer function test_output(outdata)
integer, intent(out) :: outdata(10)
integer :: i
outdata = (/(i, i=1, 10)/)
! All worked well
test_output = 0
return
end function test_output
end module mod_test
program test
! The 'USE' statement is the only thing that needs to be
! *ahead* of the 'implicit none'
use mod_test
implicit none
integer :: mydata(10) ! The variable that will contain the data
! from the function
integer :: status ! The variable that will contain the error
! code.
status = test_output(mydata)
if (status == 0) then
print*, mydata
end if
end program test
如果模块位于不同的源文件中,则需要以这种方式编译它们,假设您使用gfortran:
显示您的代码。我不太清楚你在描述什么。你的函数返回什么?它是函数还是子程序?您知道模块吗?您应该需要在函数def中指定变量作为参数:实函数数据_模块d1、r1、r2,。。。如果你真的使用了一个模块,这种错误会给你一个非常清晰的错误消息agentp,我敢肯定我试了5次,但都没有成功。现在我又试了一次,它神奇地起了作用。这很奇怪,但谢谢你。我知道我觉得自己有点傻,但希望它能帮助其他人上网。我找了一会儿,什么也没找到。就风格而言,这应该是一个子程序,而不是一个函数,因为你从来没有设置过函数返回值,我看不到data_module=。。在任何地方或尝试使用它。它实际上在那里,在底部。我用它来确保我读过它,但它可能毫无意义,所以我可能会使用一个子程序,谢谢,还有一个小的附加点-如果错误代码永远不会被设置为错误值,那么返回错误代码是没有意义的。是的,但由于他使用了错误代码或类似于他自己的示例中的代码,我想展示一下如何将其包括在内。另外:如果您合理地确定在不久的将来您将添加某种类型的错误检查,那么使用它会有所帮助,因为您以后不必更改太多代码。
$ gfortran -c -o mod_test.o mod_test.f90
$ gfortran -c -o test.o test.f90
$ gfortran -o test test.o mod_test.o