好的,所以我正在尝试解决一个初始值问题,尝试使用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
答案 0 :(得分:1)
我认为您的问题在于您的函数f
,特别是在这一行:
f = -(gr)-((c1/m)*v)
该函数有自己的作用域,即函数无法访问您在主程序中赋值的变量,而是它有自己的变量gr
,{{1} }和c1
。只传递m
和t
,但该函数的结果仍然太小,无法在y
中注册任何有意义的更改。 (当我运行代码时,v
的结果大约为f
,但由于您从未初始化函数内部的变量,因此您的值可能会有所不同。)
至于你能做什么:
将-2e-314
,gr
和c1
的初始化移至函数中。无论如何,这些值似乎都没有改变。
将整个函数移动到主程序中,并从函数中删除m
,gr
和c1
的显式声明。这样它将在父母的范围中寻找变量:
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
,gr
,c1
或m
。
将函数及其所依赖的变量放入模块中:
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
等声明,因为这些变量由模块提供。
还有很多其他问题,这里只是几个例子:
gr
和t
但从未实际使用它们y
上打开一个文件,这可能会干扰其他I / O,具体取决于您的编译器。我只使用单位> 10,甚至更好,为我的单位声明一个整数,并使用1
作为开放,然后使用open(newunit=myunit, file=....)
和read(myunit, ...
您对write(myunit, ...
的使用与编译器无关。更好的是这样的:
real(8)
但这不是问题所在,所以我会把它留下来。