作为参数传递一个内部过程 [英] Passing an internal procedure as argument

查看:160
本文介绍了作为参数传递一个内部过程的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想为不同的参数多次解微分方程。它比这更复杂,但为了清楚起见,我们假设ODE是 y'(x)=(y + a)* x ,其中 y(0)= 0 ,我想 y(1)。我从netlib中选择了dverk算法来解决ODE问题,并且期望右侧的函数具有某种形式。现在我用英特尔Fortran编译器做了以下事情(简化):

$ $ $ $ $ $ $ $ $子程序f(x,a,ans)
implicite none
double precision f,a,ans,y,tol,c(24),w(9)
...
call dverk(1,faux,x, y,1.d0,tol,ind,c,1,w)
...
包含
子程序faux(n,xx,yy,yprime)
implicite none
整数n
双精度xx,yy(n),yprime(n)
yprime(1)=(yy(1)+ a)* xx
结束子程序faux
结束子程序f

这适用于ifort,子子程序 faux 看到参数 a ,并且所有内容都按预期工作。但是我希望代码与gfortran兼容,并且使用此编译器,我收到以下错误消息:


错误:内部过程(1)


我不能使用'faux'作为实际参数我需要 faux 例程在 f 中,否则我不知道如何告诉它 a ,因为我无法更改参数列表,因为这是 dverk 例程所期望的。



我想保留 dverk 例程,并理解如何在没有解决方法的情况下解决这个特定问题,因为我觉得当我需要将参数化函数与不同的集成商。

解决方案

您可以将这一切放在模块中,并使 a 一个全局模块变量。使 faux 模块过程。这样,它可以访问 a

 模块ode_module 
双精度:: a

包含

子程序f(x,a,ans)
隐式无
双精度f,ans,y,tol,c(24),w(9)

调用dverk (1,faux,x,y,1.d0,tol,ind,c,1,w)

结束子程序

子程序faux(n,xx,yy, yprime)
implicite none
integer n
double precision xx,yy(n),yprime(n)
yprime(1)=(yy(1)+ a)* xx
结束子程序人为

结束模块


I want to solve a differential equation lots of times for different parameters. It is more complicated than this, but for the sake of clarity let's say the ODE is y'(x) = (y+a)*x with y(0) = 0 and I want y(1). I picked the dverk algorithm from netlib for solving the ODE and it expects the function on the right hand side to be of a certain form. Now what I did with the Intel Fortran compiler is the following (simplified):

subroutine f(x,a,ans)
implicite none
double precision f,a,ans,y,tol,c(24),w(9)
...
call dverk(1,faux,x,y,1.d0,tol,ind,c,1,w)
...
contains
    subroutine faux(n,xx,yy,yprime)
           implicite none
           integer n
           double precision xx,yy(n),yprime(n)
           yprime(1) = (yy(1)+a)*xx
    end subroutine faux
end subroutine f

This works just fine with ifort, the sub-subroutine faux sees the parameter a and everything works as expected. But I'd like the code to be compatible with gfortran, and with this compiler I get the following error message:

Error: Internal procedure 'faux' is not allowed as an actual argument at (1)

I need to have the faux routine inside f, or else I don't know how to tell it the value of a, because I can't change the list of parameters, since this is what the dverk routine expects.

I would like to keep the dverk routine and understand how to solve this specific problem without a workaround, since I feel it will become important again when I need to integrate a parameterized function with different integrators.

解决方案

You could put this all in a module, and make a a global module variable. Make faux a module procedure. That way, it has access to a.

module ode_module
    double precision::a

    contains

    subroutine f(x,a,ans)
        implicit none
        double precision f,ans,y,tol,c(24),w(9)

        call dverk(1,faux,x,y,1.d0,tol,ind,c,1,w)

    end subroutine 

    subroutine faux(n,xx,yy,yprime)
       implicite none
       integer n
       double precision xx,yy(n),yprime(n)
       yprime(1) = (yy(1)+a)*xx
    end subroutine faux

end module

这篇关于作为参数传递一个内部过程的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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