如何将数组传递给一个过程,该过程作为参数传递给使用 Fortran 的另一个过程 [英] How to pass array to a procedure which is passed as an argument to another procedure using Fortran

查看:17
本文介绍了如何将数组传递给一个过程,该过程作为参数传递给使用 Fortran 的另一个过程的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试将另一个 subroutine_b 的名称和一个数组传递给通用 subroutine_a.这个 subroutine_a 应该将数组传递给 subroutine_b 并取回其计算值.

I am trying to pass the name of another subroutine_b and an array to a generic subroutine_a. This subroutine_a is supposed to pass the array to subroutine_b and get back its computed value.

以下是我写的代码:

module pass_subroutine_mod1
    implicit none
    private
    public :: ave_value, fx

    contains
        subroutine ave_value( func, x, y, ave )
            ! Calculate average of y which is passed on from another function `func`.
            !
            external :: func
            double precision, intent(in), dimension(:) :: x
            double precision, intent(inout), dimension(:) :: y
            double precision, intent(inout) :: ave

            integer :: n

            N = size( x )

            call func( x, y )
            ave = sum( y ) / dble( N )

            return
        end subroutine ave_value


        subroutine fx( x, y )
            double precision, dimension(:), intent(in) :: x
            double precision, dimension(:), intent(inout) :: y

            y = x ** 3
            return
        end subroutine fx
end module pass_subroutine_mod1


program main
    use :: pass_subroutine_mod1
    implicit none

    integer :: i, N = 101
    double precision :: ave
    double precision, allocatable, dimension(:) :: x, y
    allocate( x(N), y(N), source=0.0d0 )

    do i = 1, N
        x(i) = dble( i - 1 )
    end do

    call ave_value( fx, x, y, ave )
    write( *, '(A, ES15.6E3)' ) "Average value of y (from fx) = ", ave

    deallocate( x, y )
end program main

这里ave_value()是subroutine_a,fx()是subroutine_b.

Here ave_value() is the subroutine_a and fx() is subroutine_b.

当我编译并运行上面的代码时,它会抛出以下错误:

When I compile and run the above code, it throws the following error:

At line 28 of file pass_subroutine.f90
Fortran runtime error: Array bound mismatch for dimension 1 of array 'y' (1/1125899906842625)

Line 28 是子程序fx( x, y ) 中的y = x ** 3 行.因此,数组 xy 似乎没有正确传递给 fx() 因为当我尝试打印 xfx() 中的 code>,它无法这样做.

Line 28 is the line y = x ** 3 in subroutine fx( x, y ). It thus seems that the arrays x and y are not properly passed to fx() because when I try to print x from within fx(), it is unable to do so.

如果我使用标量(并相应地更新代码)而不是数组 xy,则代码能够正常运行并输出所需的结果.

If, instead of arrays x and y, I use scalars (and update the code accordingly) the code is able to run properly and output the desired result.

此外,经过 this thread,如果我通过添加接口块来修改 ave_value,代码会再次正常运行.以下是 ave_value 的修改:

Additionally, after going through this thread, if I modify the ave_value by adding an interface block, the code runs properly again. Following is the modification with ave_value:

        subroutine ave_value( func, x, y, ave )
            ! Calculate average of y which is passed on from another function `func`.
            !
            external :: func
            double precision, intent(in), dimension(:) :: x
            double precision, intent(inout), dimension(:) :: y
            double precision, intent(inout) :: ave

            integer :: n

            interface
                subroutine func( ip, op )
                    double precision, dimension(:), intent(in) :: ip
                    double precision, dimension(:), intent(inout) :: op
                end subroutine func
            end interface

            N = size( x )

            call func( x, y )
            ave = sum( y ) / dble( N )

            return
        end subroutine ave_value

因此,我的问题是:

a) 上述修改是否正确?

a) Is the above modification correct?

b) 如果是,那么为什么在处理数组时需要接口块而不是在处理标量时需要接口块?

b) If yes, then why do I need an interface block when working with arrays and not when working with scalars?

推荐答案

需要显式接口的是假定形状的数组虚拟参数 dimension(:).这是因为编译器必须为这些做一些不同的事情,通常是传递一个描述符.调用方的内容并不重要,重要的是被调用过程的虚拟参数.

It's the assumed-shape array dummy arguments dimension(:) that require an explicit interface. This is because the compiler has to do something different for these, typically passing a descriptor. It doesn't matter what's on the calling side, it's the dummy arguments of the called procedure that matter.

有关更多信息,请参阅我的旧博文 Doctor Fortran 变得明确 - 再次!

For more information see my old blog post Doctor Fortran Gets Explicit - Again!

您可能需要查看语言特性 abstract interface 以及 procedure,以使代码看起来更简洁.

You may want to look at the language feature abstract interface, along with procedure, to make the code look a bit cleaner.

这篇关于如何将数组传递给一个过程,该过程作为参数传递给使用 Fortran 的另一个过程的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆