Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/fortran/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Arrays 虚拟过程中的界面不匹配:形状不匹配_Arrays_Fortran - Fatal编程技术网

Arrays 虚拟过程中的界面不匹配:形状不匹配

Arrays 虚拟过程中的界面不匹配:形状不匹配,arrays,fortran,Arrays,Fortran,我正试图实现一个微分方程组的龙格库塔。 我的子程序有点问题。我想让它成为一个通用代码,通过任何方程组来求解 该程序的主要代码是: program main use ivp_odes implicit none double precision, allocatable :: t(:), y(:,:) double precision :: t0, tf, y0(2), h integer :: i t0 = 0d0 tf = 0.5d0

我正试图实现一个微分方程组的龙格库塔。 我的子程序有点问题。我想让它成为一个通用代码,通过任何方程组来求解

该程序的主要代码是:

program main

use ivp_odes

    implicit none

    double precision, allocatable :: t(:), y(:,:)
    double precision :: t0, tf, y0(2), h
    integer :: i

    t0 = 0d0
    tf = 0.5d0
    y0 = [0d0, 0d0]
    h = 0.1d0

    do i=lbound(t,1),ubound(t,1)
        print *, t(i), y(1,i), y(2,i)
    end do

contains

function myfun(t,y) result(dy)

    ! input variables
    double precision, intent(in) :: t, y(2)

    ! output variables
    double precision :: dy(2)

    dy(1) = -4*y(1) + 3*y(2) + 6
    dy(2) = -2.4*y(1) + 1.6*y(2) + 3.6
end function myfun

end program main
myfun
是一个示例函数,我有解析解,因此我可以将我的实现与系统的正确响应进行比较。这个
myfun
函数获取一个变量
t
和一个由两个元素组成的一维数组
y
,并返回其导数,因此我可以对其进行数值积分

我在单独模块中实现的龙格库塔算法:

module ivp_odes
    implicit none
contains

subroutine rk4(t, y, f, t0, tf, y0, h)
    ! input variables
    double precision, intent(in) :: t0, tf, y0(1:)
    double precision, intent(in) :: h

    interface
        pure function f(t,y) result(dy)
            double precision, intent(in) :: t, y(:)
            double precision :: dy(size(y))
        end function
    end interface

    ! output variables
    double precision, allocatable :: t(:), y(:,:)

    ! auxiliar variables
    integer :: i, m, N
    double precision :: hh
    double precision, allocatable :: k1(:), k2(:), k3(:), k4(:)

    N = ceiling((tf-t0)/h)
    m = size(y0)

    allocate(k1(m),k2(m),k3(m),k4(m))

    if (.not. allocated(y)) then
        allocate(y(m,0:N))
    else
        deallocate(y)
        allocate(y(m,0:N))
    end if

    if (.not. allocated(t)) then
        allocate(t(0:N))
    else
        deallocate(t)
        allocate(t(0:N))
    end if

    t(0) = t0
    y(:,0) = y0

    do i=1,N
        k1(:) = h * f(t(i-1)      , y(:,i-1)        )
        k2(:) = h * f(t(i-1)+h/2 , y(:,i-1)+k1(:)/2)
        k3(:) = h * f(t(i-1)+h/2 , y(:,i-1)+k2(:)/2)
        k4(:) = h * f(t(i-1)+h   , y(:,i-1)+k3(:)  )

        y(:,i) = y(:,i-1) + (k1(:) + 2*k2(:) + 2*k3(:) + k4(:))/6
            t(i) = t(i-1) + h
        end do

        deallocate(k1,k2,k3,k4)

end subroutine rk4

end module ivp_odes
rk
子例程的思想是
t
是时间向量(一维数组),
y
是响应向量(二维数组,每行对应一个变量,每列对应相应时间内变量的值)

我找不到方法使它工作,因为我在编译代码时会出错,所有这些都与调用主代码中的子例程
rk
时的函数
myfun
有关

call rk4(t, y, myfun, t0, tf, y0, h)
                   1
Error: Interface mismatch in dummy procedure 'f' at (1): Shape mismatch in dimension 1 of function result
我试图寻找这个问题的答案,并且已经阅读了之前提出的问题:

其中一些已经帮助我解决了一些错误。然而,我想做的和第一个问题差不多,但根本不起作用

我正在使用GNU Fortran编译器,并在code::Blocks 16.01中编写代码。 找不到解决的办法

以下是我尝试过的一些不起作用的东西:

  • 更改界面中的变量:
  • 不在接口中声明函数的结果
它会产生以下错误:

    call rk4(t, y, myfun, t0, tf, y0, h)
                   1
Error: Interface mismatch in dummy procedure 'f' at (1): Type mismatch in function result (REAL(4)/REAL(8))
  • 我想我可以使用procedure语句,但我认为要做到这一点,我应该在子例程的同一个模块中声明我的函数myfun,对吗?但是有一个通用代码的想法是,我不需要在完成后打开这个模块,所以任何时候我想使用rk4积分器,我只需要调用它,不需要在同一个模块中指定函数

您传递的函数
myfun
和子例程
rk4
期望的函数
f
不是同一类型:

  • f
    pure
    ,而
    myfun
    不是
  • f
    中,
    y
    是延迟形状,而在
    myfun
    中它是显式形状(对
    dy
    有影响)
这实际上就是编译器所抱怨的:)
一旦解决了这些问题,代码就可以很好地编译

虽然它是关于假定的大小而不是假定的形状,但大部分细节都在这里。我更改了
myfun
,因此它现在是
纯的
,并且
y
具有延迟的形状。但是现在我注意到另一个问题,在
rk
子例程中的do循环中,语句
y(:,I)=y(:,I-1)+(k1(:)+2*k2(:)+2*k3(:)+k4(:)/6
删除数组
y
的先前值。为什么会这样?在第i个循环中,它不应该只更改第i列中的
y
的值吗?由于Fortran已经实现了元素操作,因此代码阅读起来更清晰,我认为这比循环分配每个元素运行得更快。@Thales这可能会进入一个单独的问题:)但请提供更多关于此行为的信息。我不清楚你所说的“擦除”是什么意思。
interface
    pure function f(t,y)
        double precision, intent(in) :: t, y(:)
    end function
end interface
    call rk4(t, y, myfun, t0, tf, y0, h)
                   1
Error: Interface mismatch in dummy procedure 'f' at (1): Type mismatch in function result (REAL(4)/REAL(8))