我正在尝试使用MUESLI库的数值集成函数mfOdeSolve,但是我收到了编译错误。 就像在用户指南的示例(#4-52)中一样,我将代码分为主程序和外部模块:
主:
program ode
use odemod
use fml
real (kind = MF_DOUBLE) :: t_0, t_end
type(mfArray) :: t_span, y_0, y_end
print *, "integration of {y'' = - y} over [0,pi]:"
print *, " [ solution is: y(t) = sin(x) ]"
t_0 = 0.0d0
t_end = MF_PI
t_span = .t. mfLinSpace( t_0, t_end, 10 )
y_0 = [0, 1]
y_end = mfOdeSolve( deriv, t_span, y_0)
call msDisplay( y_end, "numerical result" )
end program
模块:
module odemod
use fml
contains
subroutine deriv( t, y, yprime )
real(kind=MF_DOUBLE), intent(in) :: t, y(*)
real(kind=MF_DOUBLE) :: yprime(*)
yprime(1) = y(2)
yprime(2) = -y(1)
end subroutine
end module
模块编译时没有任何问题,但是主程序出现以下错误:
y_end = mfOdeSolve(deriv,t_span,y_0)
1
错误:(1)
处的通用'mfodesolve'没有特定的功能
我查看了参考手册,但仍无法修复此问题。有什么想法吗?
用户指南:http://people.irisa.fr/Edouard.Canot/muesli/muesli_user_guide.pdf
参考手册:http://people.irisa.fr/Edouard.Canot/muesli/muesli_ref_manual.pdf
答案 0 :(得分:1)
“用户指南”(第一页PDF)的第41页确实显示了
的示例(#4-52)! definition of a user-subroutine (actually in an external module)
subroutine deriv( t, y, yprime )
real(kind=MF_DOUBLE), intent(in) :: t, y(*)
real(kind=MF_DOUBLE) :: yprime(*)
yprime(1) = y(2)
yprime(2) = -y(1)
end subroutine
...
但是,参考手册(第二篇PDF)的第371页描述了mfOdeSolve
的界面
function mfOdeSolve( deriv, t_span, y_0 [, options, jac, sparse] ) result( out )
interface
subroutine deriv( t, y, yprime, flag )
real(kind=MF_DOUBLE), intent(in) :: t, y(*)
real(kind=MF_DOUBLE), intent(out) :: yprime(*)
integer, intent(in out) :: flag
end subroutine
end interface
type(mfArray), intent(in) :: t_span, y_0
type(mf_DE_Options), intent(in), optional :: options
external, optional :: jac
logical, intent(in), optional :: sparse
type(mfArray) :: out
因此,虚拟子例程参数deriv
的定义似乎略有不同,因为(1)intent(out)
附加在yprime
上,(2)它具有flag
变量也。后一本手册还介绍了如何详细设置flag
。
那么,第一本PDF手册可能还没有更新......?您可以尝试上面的第二个定义,看看是否可以获得预期的结果(在第一本手册中)。
subroutine deriv( t, y, yprime, flag )
real(kind=MF_DOUBLE), intent(in) :: t, y(*)
real(kind=MF_DOUBLE), intent(out) :: yprime(*)
integer, intent(inout) :: flag !! no modification (as a test)
yprime(1) = y(2)
yprime(2) = -y(1)
end subroutine
答案 1 :(得分:1)
参考手册(第371页)显示deriv
的第一个参数mfOdeSolve
应该是一个包含四个参数的子例程。
您的代码(以及用户手册中的示例)只有三个参数。
integer, intent(inout) :: flag
应该有一个额外的deriv
伪参数。
(编译器投诉有点误导 - 虚拟过程的参数的特征不用于通用解析 - 只是“过程性”和(如果过程已知是一个函数)函数的类型因此,编译器可以直接抱怨实际过程中伪参数特征的不匹配。)