MUESLI数值库的积分函数出错

时间:2016-09-04 01:45:58

标签: fortran integration ode numerical

我正在尝试使用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

2 个答案:

答案 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伪参数。

(编译器投诉有点误导 - 虚拟过程的参数的特征不用于通用解析 - 只是“过程性”和(如果过程已知是一个函数)函数的类型因此,编译器可以直接抱怨实际过程中伪参数特征的不匹配。)