我对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 中,但这样做不会保存它们(如果你运行它,当你打印它们"之前"一切都很好,当你打印它们"之后"时,你得到全零。
好的,我注意到了一些事情。
-
您的
function
类型为real
,但您仅将其设置为 1(整数),正如您在注释"显示函数已正确执行"中所说的那样。 让过程返回一个值以显示它是否正确执行的情况并不少见,但它通常是一个错误代码,零表示没有发生错误并且一切正常。 此外,您可能希望将函数声明为integer
而不是real
,因为整数更适合这种事情。(比较更可靠。 -
至于你的实际问题:如果你想将多个值传递回调用例程,你需要声明
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
-
模块是要走的路。下面是一个非常有限的示例,介绍如何将上述函数合并到模块中,并在程序中使用该模块:
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