4

多くのタイプ(球、平面、NURBSサーフェス、stlファイルなど)のジオメトリを科学的なFortranコードにインポートするためのライブラリを作成しています。type :: geomこの種の問題は、aやthenなどを定義するのが簡単であるため、OOPにとってはテーラーメイドのようtype,extends(geom) :: analyticです。私が問題を抱えているのはファイルIOです。

この時点での私の解決策は、形状を定義するパラメーターを作成することです。これには、形状を示すいくつかのフラグが含まれます。読むとき、私class(geom) :: objectは(それがどのサブタイプになるかを前もって知らないので)インスタンス化しますが、どうすればそれを読むことができますか?

サブタイプの特定のコンポーネントにアクセスできません。ダウンキャスティングは冗長であり、その上、新しいallocate(subtype :: class)ものは機能していないようだと読みました。新しいREAD(FORMATTED)ものはifortやgfortranによって実装されていないようです。すなわち

module geom_mod
  type :: geom
  end type
  type,extends(geom) :: sphere
    integer :: type
    real(8) :: center(3),radius
   contains
    generic :: READ(FORMATTED)=> read_sphere ! not implemented anywhere
  end type
contains
  subroutine read_geom(object)
    class(geom),intent(out),pointer :: object     
    integer :: type

    read(10,*) object%type   ! can't access the subtype data yet

    read(10,*) type
    backspace(10)
    if(type==1) then
      allocate(sphere :: object)! downcast?
      read(10,*) object         ! doesn't work
    end if 

  end read_geom
end module

私はこれについてすべて間違っていますか?ポリモーフィズム以外のものを使用してこれをハックすることはできますが、これは他のすべての場所でよりクリーンに見えます。支援をいただければ幸いです。

編集:IanHのモジュールを使用したサンプルプログラム

program test
  use geom_mod
  implicit none
  class(geom),allocatable :: object

  open(10)
  write(10,*) '1'
  write(10,*) sphere(center=0,radius=1)
  rewind(10)

  call read(object) ! works !
end program test
4

1 に答える 1

4

現在の gfortran と ifort は、定義された入出力を実装していません。この状況が近い将来に変わるという証拠は見たことがありません。ただし、いくつかの構文上のショートカットを許可することを除けば、この機能によって実際に多くの作業が節約されるわけではありません。

この状況の 1 つのアプローチは、ファイル内のデータを使用して引数を正しい型に割り当てる geom の拡張機能の「ファクトリ」を呼び出してから、型固有のデータを読み取る型バインド プロシージャに渡すことです。例えば:

module geom_mod
  implicit none
  integer, parameter :: dp = kind(1.0d0)
  type, abstract :: geom
  contains
    procedure(read_geom), deferred :: read
  end type geom

  abstract interface
    subroutine read_geom(object)
      import :: geom
      implicit none
      class(geom), intent(out) :: object
    end subroutine read_geom
  end interface

  type, extends(geom) :: sphere
    real(dp) :: center(3), radius
  contains
   procedure :: read => read_sphere
  end type sphere
contains
  subroutine read(object)
    class(geom), intent(out), allocatable :: object
    integer :: type
    read (10, *) type
    ! Create (and set the dynamic type of object) based on type.
    select case (type)
    case (1)     ; allocate(sphere :: object)
    case default ; stop 'Unsupported type index'
    end select
    call object%read
  end subroutine read

  subroutine read_sphere(object)
    class(sphere), intent(out) :: object
    read (10, *) object%center, object%radius
  end subroutine read_sphere
end module geom_mod

現在の ifort (12.1.5) には、回避策が必要な可能性があるインテント (アウト) ポリモーフィック引数に関する問題がありますが、一般的なアプローチは同じままです。

(サブルーチン read はタイプ バインド サブルーチンではないことに注意してください。一般的な geom オブジェクトを読み取るには、従来のサブルーチン参照スタイルで「call read(object)」を使用します。)

于 2012-07-20T03:50:22.730 に答える