fortran中的函数,传入数组,接收数组 [英] Function in fortran, passing array in, receiving array out

查看:25
本文介绍了fortran中的函数,传入数组,接收数组的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有这个功能,如下图所示.它传入两个向量,每个向量具有三个值,并且应该传递一个具有三个值的向量.我这样调用函数:

I have this function, depicted below. It passes in two vectors with three values each, and should pass out one vector with three values as well. I call the function like this:

Fr       = Flux(W(:,i),W(:,i+1))

我通过弄乱代码、尝试纯函数和模块以及研究错误语句(我将在底部包含)意识到的是,fortran 正在读取我的函数 Flux,并认为输入向量是尝试从数组中调用一个条目.这是我对正在发生的事情的最佳猜测.我在实验室里四处询问,大多数人建议使用子程序,但这似乎很笨拙,我想应该有一个更优雅的方法,但我还没有找到.我试图通过以下方式定义结果:

What I have realized through messing around with the code, trying pure functions, and modules, and researching the error statement (that I will include at the bottom), is that fortran is reading my function Flux, and thinks that the input vectors are an attempt to call an entry from the array. That is my best guess as to what is going on. I asked around the lab and most people suggested using subroutines, but that seemed clunky, and I figured there should probably be a more elegant way, but I have not yet found it. I tried to define a result by saying:

 DOUBLE PRECISION FUNCTION Flux(W1,W2) Result(FluxArray(3))

然后返回fluxarray,但这不起作用,因为fortran无法理解语法

and then returning fluxarray but that does not work, as fortran cannot understand the syntax

实际功能是这样的:

DOUBLE PRECISION FUNCTION Flux(W1,W2)
USE parameters
IMPLICIT NONE
DOUBLE PRECISION, DIMENSION(3), INTENT(IN)::W1, W2
DOUBLE PRECISION, DIMENSION(3), INTENT(OUT):: Flux
DOUBLE PRECISION, DIMENSION(3):: F1, F2
DOUBLE PRECISION::U1,U2,Rh1,Rh2,P1,P2,E1,E2,Rh,P,u,c,Lambda
INTEGER:: k
U1=W1(2)/W1(1)
U2=W2(2)/W2(1)

Rh1=W1(1)
Rh2=W2(1)

P1=(gamma_constant-1.d0)*(W1(3)-.5d0*Rh1*U1**2)
P2=(gamma_constant-1.d0)*(W2(3)-.5d0*Rh2*U2**2)

E1=W1(3)
E2=W2(3)

F1=[Rh1*U1,Rh1*U1**2+P1,(E1+P1)*U1]
F2=[Rh2*U2,Rh2*U2**2+P2,(E2+P2)*U2]

Rh=.5d0*(Rh1+Rh2)
P=.5d0*(P1+P2)
u=.5d0*(U1+U2)
c=sqrt(gamma_constant*P/Rh)

Lambda=max(u, u+c, u-c)
do k=1,3,1
    Flux(k)=.5d0*(F1(k)+F2(k))-.5d0*eps*Lambda*(W2(k)-W1(k))
end do
RETURN
END FUNCTION Flux

这是错误声明:

Quasi1DEuler.f90:191.51:

DOUBLE PRECISION, DIMENSION(3), INTENT(OUT):: Flux
                                               1
Error: Symbol 'flux' at (1) already has basic type of REAL
Quasi1DEuler.f90:217.58:

Flux(k)=.5d0*(F1(k)+F2(k))-.5d0*eps*Lambda*(W2(k)-W1(k))
                                                      1
Error: Unexpected STATEMENT FUNCTION statement at (1)
Quasi1DEuler.f90:76.18:

Fr      = Flux(W(:,i),W(:,i+1))

最后一个错误发生在 Fr 和 Fl 上.感谢您的宝贵时间以及您可以提供的任何帮助或考虑!

The last error occurs for both Fr and Fl. Thank you for your time and any help or consideration you can give!

编辑/跟进::感谢您的帮助,我不知道更好的方式来呈现这个,所以我要编辑最初的问题.

EDIT/Follow-up:: Thanks for the help, I don't know a better way to present this so I'm going to edit the initial question.

我按照你的建议做了,它解决了这个问题,现在它说:

I did as you suggested and It solved that issue, now it says:

Fr      = Flux(W(:,i),W(:,i+1))
         1
Error: The reference to function 'flux' at (1) either needs an explicit INTERFACE or the rank is incorrect  

我在这个链接上看到了类似的问题:

I saw a similar issue on SO at this link:

在 Fortran 中计算两个向量的叉积90

他们建议他将所有功能放入模块中.有没有更好/更简单的方法来修复此错误?

where they suggested that he put all his functions into modules. is there a better/simpler way for me to fix this error?

推荐答案

使用RESULT(FluxArray)fluxArray就是name结果变量.因此,您在结果子句中声明特征的尝试是错误的.

With RESULT(FluxArray), fluxArray is the name of the result variable. As such, your attempt to declare the characteristics in the result clause are mis-placed.

相反,结果变量应该在函数体中指定:

Instead, the result variable should be specified within the function body:

function Flux(W1,W2) result(fluxArray)
  double precision, dimension(3), intent(in)::W1, W2
  double precision, dimension(3) :: fluxArray  ! Note, no intent for result.
end function Flux

是的,可以在 function 语句中声明结果变量的类型,但不能在那里声明数组.我不建议在结果变量的函数体中使用不同的 dimension 语句.

Yes, one can declare the type of the result variable in the function statement, but the array-ness cannot be declared there. I wouldn't recommend having a distinct dimension statement in the function body for the result variable.

请注意,当引用返回数组的函数时,调用者需要有一个显式接口.一种方法是将函数放在 used 的模块中.有关更多详细信息,请参阅 SO 或语言教程的其他地方.

Note that, when referencing a function returning an array it is required that there be an explicit interface available to the caller. One way is to place the function in a module which is used. See elsewhere on SO, or language tutorials, for more details.

在没有 result 的情况下从您的问题中得出错误.

Coming to the errors from your question without the result.

DOUBLE PRECISION FUNCTION Flux(W1,W2)
  DOUBLE PRECISION, DIMENSION(3), INTENT(OUT):: Flux

这里 Flux 的类型已经声明了两次.此外,它不是函数的虚拟参数,因此如上所述,它不需要 intent 属性.

Here the type of Flux has been declared twice. Also, it isn't a dummy argument to the function, so as above it need not have the intent attribute.

可以写

FUNCTION Flux(W1,W2)
  DOUBLE PRECISION, DIMENSION(3) :: Flux  ! Deleting intent

或(颤抖)

DOUBLE PRECISION FUNCTION Flux(W1,W2)
  DIMENSION :: Flux(3)

关于声明函数的抱怨在这里并不重要,继错误声明之后.

The complaint about a statement function is unimportant here, following on from the bad declaration.

这篇关于fortran中的函数,传入数组,接收数组的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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