Fortran“全局”变量与Matlab函数句柄

时间:2019-04-12 20:30:17

标签: matlab fortran global-variables ode

给出一个以状态空间形式表示的微分方程的线性系统,

dy = A*y + b

在Matlab中,我可以定义函数

function [dy] = fun(t,y,A,b)
    dy = A*y+b;
end

如果我想进行时间积分,可以在主程序中编写:

n = size(M,1);
A = [zeros(n,n) eye(n,n) ; -M\K -M\C];
b = [zeros(n,1) M\F];
odefun = @(t,y) fun(t,y,A,b)

[TOUT,YOUT] = ode15s(odefun,tspan,y0);

前提是我之前已经定义了MCK矩阵以及力矢量F,时间跨度tspan和初始条件{{ 1}}。


现在我要在Fortran中使用它。为此,我找到了一个ode求解器online。这是Shampine和Gordon ODE求解器(可能与MATLAB中使用的求解器相同),它集成了形式为的微分方程

y0

就像MATLAB! 如果我定义了一个子程序,例如(the online example

y' = f(t,y)

我可以整合这个方程组。

subroutine fun( t, y, yp )
    implicit none
    double precision :: t
    double precision :: y(2)
    double precision :: yp(2)

    yp(1) = y(2)
    yp(2) = -y(1)

    return
end subroutine fun

这工作正常,我可以在主程序上测试ode求解器:

subroutine test01()
    implicit none

    integer :: neqn = 2
    double precision :: abserr
    external fun
    integer :: i
    integer :: iflag
    integer :: iwork(5)
    double precision :: pi = 3.141592653589793D+00
    double precision :: relerr
    integer, parameter :: step_num = 12
    double precision :: t
    double precision :: tout
    double precision :: work(100+21*neqn)
    double precision :: y(neqn)

    abserr = 0.00001D+00
    relerr = 0.00001D+00

    iflag = 1

    t = 0.0D+00
    y(1) = 1.0D+00
    y(2) = 0.0D+00

    write ( *, '(2x,f8.4,2x,2g14.6)' ) t, y(1:neqn)

    do i = 1, step_num

    tout = dble(i)*2.0d0 * pi / dble(step_num)
    call ode ( f01, neqn, y, t, tout, relerr, abserr, iflag, work, iwork )

    if ( iflag /= 2 ) then
      write ( *, '(a)' ) 'TEST01 - Fatal error!'
      write ( *, '(a,i8)' ) '  ODE returned IFLAG = ', iflag
      exit
    end if

    write ( *, '(2x,f8.4,2x,2g14.6)' ) t, y(1:neqn)

    end do

    return
end subroutine test01

这是问题所在。现在,我想对状态空间形式的方程式进行时间积分。问题:如何将变量program main call test01() end program main A传递给fun函数以进行集成?

b

我无法更改函数定义中的参数数量,因为ode积分器只需要subroutine fun( t, y, yp ) implicit none double precision :: t double precision :: y(:) double precision :: yp(:) yp = matmul(A,y) + b return end subroutine fun 即可。

Fortran中是否有类似MATLAB的东西,我可以在其中定义函数fun(t,y,yp)和第二个函数fun(t,y,yp,A,b)并集成第二个函数?

还是告诉Fortran A和b是某种全局变量? (我虽然使用了通用块,但它不接受可分配地址)

0 个答案:

没有答案