只获得我的Fortran Runge-Kutta零

时间:2017-06-27 01:14:09

标签: fortran fortran90

好的,所以我正在尝试解决一个初始值问题,尝试使用Runge-Kutta 2找到f函数给出的速度。我的程序编译,但是当我运行它给我同样的任何时候v的值,但我无法找到我做错的地方。有人能帮助我吗?

program runge
implicit none

real(8) :: f,t,y,g,v,c1
real(8) a,b,h
real(8) k1,k2,l1,l2,v0,gr,m
integer i,n,j

n=10
a=0
b=100
h=(b-a)/n
gr=9.8100
m=70.0
c1=15.0
v0=20.0
y=0.0

v=v0
t=a

open(1, file="velocidad.txt")
write(1,*) a,v
print*, "       t", "       v"

do i=1,n

    k1 = f(t,v)
    k2 = f(t + h, v + h*k1)
    v = v + h*(k1 + k2)/2
    t = a + i*h

    write(1,*) t, v
    print*, t, v

end do
close(1)

end program runge

real(8) function f(t,y)
  implicit none
  real(8) :: t,y,c1,gr,v,m

  f = -(gr)-((c1/m)*v)

 end function f

当我运行它时,我得到并输出如下:

t               v
10.000000000000000        20.000000000000000
20.000000000000000        20.000000000000000
30.000000000000000        20.000000000000000
40.000000000000000        20.000000000000000
50.000000000000000        20.000000000000000
60.000000000000000        20.000000000000000
70.000000000000000        20.000000000000000
80.000000000000000        20.000000000000000
90.000000000000000        20.000000000000000
100.00000000000000        20.000000000000000

1 个答案:

答案 0 :(得分:1)

我认为您的问题在于您的函数f,特别是在这一行:

f = -(gr)-((c1/m)*v)

该函数有自己的作用域,即函数无法访问您在主程序中赋值的变量,而是它有自己的变量gr,{{1} }和c1。只传递mt,但该函数的结果仍然太小,无法在y中注册任何有意义的更改。 (当我运行代码时,v的结果大约为f,但由于您从未初始化函数内部的变量,因此您的值可能会有所不同。)

至于你能做什么:

  1. -2e-314grc1的初始化移至函数中。无论如何,这些值似乎都没有改变。

  2. 将整个函数移动到主程序中,并从函数中删除mgrc1的显式声明。这样它将在父母的范围中寻找变量:

    m

    请注意,函数内部未声明program runge ... end do close(1) contains real(8) function f(t, y) implicit none real(8) :: t, y f = -(gr)-((c1/m)*v) end function f end program runge grc1m

  3. 将函数及其所依赖的变量放入模块中:

    v

    请注意,此处主程序中没有module my_mod implicit none real(8) gr, c1, m, v contains real(8) function f(t, y) ... end function end module program runge use my_mod implicit none gr = 9.81 ... end program 等声明,因为这些变量由模块提供。

  4. 还有很多其他问题,这里只是几个例子:

    • 您的函数具有虚拟变量grt但从未实际使用它们
    • 您在单元y上打开一个文件,这可能会干扰其他I / O,具体取决于您的编译器。我只使用单位> 10,甚至更好,为我的单位声明一个整数,并使用1作为开放,然后使用open(newunit=myunit, file=....)read(myunit, ...
    • 进行读写
    • 您对write(myunit, ...的使用与编译器无关。更好的是这样的:

      real(8)

    但这不是问题所在,所以我会把它留下来。