2017-04-10 3 views
1

モジュール内の関数に渡されるプログラムブロック内に配列が宣言され、作成されました。しかし、プログラムブロック内の配列の形状は、機能ブロック内の形状と異なり、実際にはエラーにつながります。 modQuadratureで関数内で渡されたFortran配列の形状が変更されました

program prgQuad 
    use modPoint2D, only: Point2D 
    use modQuadrature, only : QuadIntegrateTri2D 
    implicit none 

    ! the array in question 
    type(Point2D), dimension(:) :: pts(1: 3) 
    real :: res 

     ! populate the points 
     call pts(1) % set(0.0, 0.0) 
     call pts(2) % set(1.0, 0.0) 
     call pts(3) % set(1.0, 1.0) 

     write(*, *) shape(pts) ! prints '3' 

     ! use the points 
     res = QuadIntegrateTri2D(pts) 

end program prgQuad 

:ここではいくつかは、説明のためのコードを切り倒しています

function QuadIntegrateTri2D(pts) result(integral) 
    class(Point2D), dimension(:), intent(in) :: pts(1: 3) 
    real :: integral 
    ! other vars go here 

     write(*, *) shape(pts) ! prints '4' 

     ! actual function code goes here 

end function QuadIntegrateTri2D(pts) 

確かに、私は何かが欠けています。私はなぜ配列の形が変わるか分かりません。私はFortranが参照渡しすることを知っているので、プログラムブロックと関数は同じメモリブロックを参照しています。なぜ形状が変化するのかについての洞察は高く評価されます!ありがとう。

modPoint2D:

module modPoint2D 

    type Point2D 
     real(rp) :: x, y 
    contains 
     procedure :: set => SetPoint2D 
    end type 

contains 

    subroutine SetPoint2D(self, x, y) 
     class(Point2D), intent(out) :: self 
     real(rp),  intent(in) :: x, y 

      self % x = x 
      self % y = y 

    end subroutine SetPoint2D 

end module modPoint2D 
+1

すべてのチェックオプションを指定してコンパイルしましたか?どこかに不正アクセスがないことを確認しましたか?それを超えて、私たちのための完全な例を準備できますか? [mcve]を参照してください。 – francescalus

+2

それはとても独特です。しかし、関数引数 'pts'のサイズ/形状の2つの仕様があることも特有です。通常、私たち(古いFortranプログラマ)は一度だけ指定します。 'class(Point2D)、dimension(:)、intent(in):: pts' - * assume-shape *の引数です。 –

+0

仮引数 'pts'は、メインプログラムの' pts'というエンティティとは完全に独立して( '' pts(1:3) 'と同じです。したがって、その関数の 'shape(pts)'が異なる結果を出す場合、コンパイラやコードのどこかにバグがあります。 – francescalus

答えて

0

ptsの宣言は確かに非常に特有のものです。以下のコードは、ポイントの配列の正しい形状を意図してコンパイルして実行します。

module modPoint2D 

    type :: Point2D 
     real :: x,y 
    contains 
     procedure, pass :: set 
    end type 
    contains 

    subroutine set(pnt, px, py) 
    class(Point2D), intent(out) :: pnt 
    real, intent(in) :: px, py 

     pnt%x = px 
     pnt%y = py 

    end subroutine 
end module 


module modQuadrature 
use modPoint2D 

    contains 
    function QuadIntegrateTri2D(pts) result(integral) 
     class(Point2D), dimension(:), intent(in) :: pts 
     real :: integral 
     ! other vars go here 

      write(*, *) shape(pts) ! prints '3' 

      ! actual function code goes here 
      integral = 0 

    end function 
end module 


program prgQuad 
    use modPoint2D, only: Point2D 
    use modQuadrature, only : QuadIntegrateTri2D 
    implicit none 

    ! the array in question 
    type(Point2D), dimension(:) :: pts(1:3) 
    real :: res 

     call pts(1) % set(0.0, 0.0) 
     call pts(2) % set(1.0, 0.0) 
     call pts(3) % set(1.0, 1.0) 

     write(*, *) shape(pts) ! prints '3' 

     ! use the points 
     res = QuadIntegrateTri2D(pts) 

end program 
+0

'class(Point2D)、dimension(:)、intent(in):: pts(1:3) 'という完全な例では、問題の問題を呈していますか? – francescalus

+0

メインプログラムの 'type(Point2D)、dimension(:) :: pts(1:3)'は正しい出力を生成します。私は答えを編集します。 'QuadIntegrateTri2D()'に 'class(Point2D)、dimension(:)、intent(in):: pts(1:3)'を指定する理由はありません。 – ja72

関連する問題