2016-11-27 17 views
0

我正在Fortran工作,我正在嘗試使用子程序的一個出口作爲函數並與其一起運行,但我無法弄清楚如何正確執行。這裏是我想要做的如何將子程序的輸出之一用作函數?

module funciones 
use, intrinsic :: iso_fortran_env, only: dp => real64 
implicit none 

type ptr_wrapper 
    procedure(f), nopass, pointer :: func 
end type ptr_wrapper 

abstract interface 
function f(x1,x2) 
    import 
    real(dp), intent(in) :: x1,x2 
    real(dp) :: f 
end function f 
end interface 

abstract interface 
subroutine g(x,y,f1,f2) 
import 
real(dp), intent(in) :: x,y 
real(dp), intent(out) :: f1,f2 
end subroutine g 
end interface 

contains 
subroutine test_func(x,y,f1,f2) 
real(dp), intent(in) :: x,y 
real(dp), intent(out) :: f1,f2 

f1 = x*y 
f2 = 2d0*x+5d0*y 

end subroutine test_func 

function Derivate (x,y,fx) result (d) 
    implicit none 
    real(dp), intent(in) :: x,y 
    procedure(f), pointer :: fx 
    real(dp) :: d 

    real(dp) :: h = 1.0E-6 

    d = (1.0*fx(x-2*h,y) - 8.0*fx(x-h,y) + 8.0*fx(x+h,y) - 1.0*fx(x+2*h,y))/(12.0*h) 
end function Derivate 


function separation1(x,y,F_in) result(DF_out1) 
    implicit none 
    real(dp), intent(in) :: x,y 
    procedure(g) :: F_in 
    real(dp) :: F_out1, F_out2 
    real(dp) :: DF_out1 
    procedure (f), pointer:: F1_ptr 
    Call F_in (x,y,F_out1,F_out2) 
    F1_ptr => F_out1 
    DF_out1 = Derivate(x,y,F1_ptr) 
end function separation1 

function separation2(x,y,F_in) result(F_out2) 
    implicit none 
    real(dp), intent(in) :: x,y 
    procedure(g) :: F_in 
    real(dp) :: F_out1, F_out2 
    Call F_in (x,y,F_out1,F_out2) 
end function separation2 


end module funciones 

program testsubroutines 
use, intrinsic :: iso_fortran_env, only: dp => real64 
use funciones 
implicit none 


print*, separation1(1d0,3d0,test_func) 
print*, separation2(1d0,3d0,test_func) 



end program testsubroutines 

所以基本上這個程序創建測試(與子程序)功能的測試程序,然後分離出局。該功能分離2工作正常,所以我決定向前邁出一步,並在分開1中實現派生它的功能。但我不知道如何將指針指向out,並且我總是會在該行中發生錯誤。

我試着也造成兩個指針

F1_ptr,F2_ptr 

(F1_ptr,F2_ptr)=>Call F_in(x,y,F_out1,F_out2) 

指派他們,但我得到

Error : Unclassifiable assignment at (1). 

如果我指定的值作爲

F1_ptr => F_out1 

我得到錯誤信息

Error: Invalid procedure pointer assignment at (1) 

,或者如果我做

F1_ptr %func => Call F_in (x,y,F_out1,F_out2) 
      1 
Error: Invalid character in name at (1) 

DF_out1 = Derivate(x,y,F1_ptr) 
        1 
Error: Type mismatch in argument ‘fx’ at (1); passed TYPE(ptr_wrapper) to REAL(8) 

我也試過這兩個變化

... 
abstract interface 
subroutine g(x,y,f1,f2) 
import 
real(dp), intent(in) :: x,y 
procedure(f),pointer :: f1,f2 
end subroutine g 
end interface 

contains 
subroutine test_func(x,y,f1,f2) 
real(dp), intent(in) :: x,y 
type (ptr_wrapper) :: f1,f2 
f1%func => x*y 
f2%func => 2d0*x+5d0*y 

...

,但我得到

f1%func => x*y 
     1 
Error: Invalid procedure pointer assignment at (1) 

和F2

所以同樣的錯誤信息,我該怎麼辦呢?

+0

你是什麼意思「輸出」輸出?這不是一個確定的捷徑。最好避免俚語,至少在標題和首次提及時。 –

+0

*「並且我總是會在該行發生錯誤。」*您應該報告錯誤。 –

+0

在一個子程序中,至少在fortran中,你可以有多個輸出,差別是一個只能有一個的函數。所以我創建了一個子程序,在我的例子中有兩個子程序,我想用它們中的一個作爲函數。歡迎對標題進行任何修改 – Daniel

回答

0

子程序test_func有兩個虛擬參數,讓子程序報告發表了兩次從子程序內一些計算結果。

在Fortran中,值不是函數

(此區分模糊,或消除,在其他一些語言,但不是在Fortran語言。)

在Fortran中,價值的東西,可能會導致當一個函數被調用,但之間的差異調用一個函數和函數本身。

問題背後的意圖對我來說並不清楚,但是如果你想公開在子程序test_func中的計算(因爲放在子程序的名字中的「func」相當混亂)作爲函數,那麼你需要編寫一個調用test_func的函數,將感興趣的輸出參數作爲函數結果傳遞回去。這樣的功能是非常簡單的,它可能是這樣的:

function get_f1_from_test_func(x, y) result(f1) 
    real(dp), intent(in) :: x 
    real(dp), intent(in) :: y 
    real(dp) :: f1 
    real(dp) :: ignored 
    call test_func(x, y, f1, ignored) 
end function get_f1_from_test_func 

該函數返回test_funcf1僞參數的值。如果您想要改爲f2參數,請編寫另一個函數。

function get_f2_from_test_func(x, y) result(f2) 
    real(dp), intent(in) :: x 
    real(dp), intent(in) :: y 
    real(dp) :: f2 
    real(dp) :: ignored 
    call test_func(x, y, ignored, f2) 
end function get_f2_from_test_func 

上述兩個功能是與由導數的fx僞參數所要求的功能的接口一致。

如上述包裝函數中局部變量的名稱所示,當調用包裝函數時,輸出虛擬參數test_func之一的結果將被丟棄。這在計算上不太可能是有效的,但是這種情況是兩個計算結果在test_func中捆綁在一起的結果。

相關問題