如何在 Fortran 中的不同文件中使用变量?



我对Fortran项目有问题,我想也许你可以帮助我。

我使用代码块作为 IDE,在那里你可以制作项目,所以我创建了一个包含两个文件的项目:一个主程序和一个功能(我不知道还能用什么,我可以使用与功能不同的东西也许)。

所以我有我的函数,可以从.txt读取值并将它们保存为实数,一切正常。我想做的是从文件 main 调用此函数并将我用函数收集的数据保存在 main 中,以便 main 保持干净。

我该怎么做?如果你愿意,我可以发布整个脚本,但我认为它不会增加更多。

编辑:正如你所问的,这里是(未删减):

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

附言。我知道模块,但是对于开放和所有其他东西,我无法让它们工作。很乐意。

我想做的是将我在 data_module 中收集的数据 d1、r1、ecc 传递给 main 并将它们保存在 main 中,但这样做不会保存它们(如果你运行它,当你打印它们"之前"一切都很好,当你打印它们"之后"时,你得到全零。

好的,我注意到了一些事情。

  1. 您的function类型为real,但您仅将其设置为 1(整数),正如您在注释"显示函数已正确执行"中所说的那样。 让过程返回一个值以显示它是否正确执行的情况并不少见,但它通常是一个错误代码,零表示没有发生错误并且一切正常。 此外,您可能希望将函数声明为integer而不是real,因为整数更适合这种事情。(比较更可靠。

  2. 至于你的实际问题:如果你想将多个值传递回调用例程,你需要声明intent(out)虚拟变量。请参阅此示例:

    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
    
  3. 模块是要走的路。下面是一个非常有限的示例,介绍如何将上述函数合并到模块中,并在程序中使用该模块:

    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):

    $ gfortran -c -o mod_test.o mod_test.f90
    $ gfortran -c -o test.o test.f90
    $ gfortran -o test test.o mod_test.o
    

相关内容

  • 没有找到相关文章

最新更新