1

パラメータを派生型に格納し、実行時に名前リストを介してファイルからロードしたいと考えています。これはコードのスケッチです:

module options_definitions
implicit none
type :: opts

integer :: option1
integer :: option2

contains
procedure :: load      => load_options

end type opts

contains

subroutine load_options(this,path_to_profiles_folder,profile_name)

class(opts),      intent(inout) :: this
character(len=*), intent(in)    :: path_to_profiles_folder
character(len=*), intent(in)    :: profile_name 
integer                         :: err, ios
logical                         :: file_exists
character(len=255)              :: err_message
character(len=255)              :: path_to_profile_folder

ASSOCIATE( option1    => this%option1, &
           option2    => this%option2)

namelist /options_nml/ option1, option2

! the following is INESSENTIAL added for completeness
!-----------------------------------------------------
path_to_profile_folder=trim(path_to_profiles_folder)//trim(profile_name)

! load options from the configuration file (namelist set above)
INQUIRE(FILE=trim(path_to_profile_folder)//'/'//trim(opt_file_name), EXIST=file_exists)   ! 'file_exists' will be TRUE if the file exists and FALSE otherwise

if (file_exists) then
   call my_open(111,trim(path_to_profile_folder)//'/'//trim(opt_file_name),&
      'Options module could not open the options configuration file')
   read(111,NML=options_nml,iostat=ios,iomsg=err_message)
   call check_read_success_and_close(111,trim(path_to_profile_folder)//'/'//trim(opt_file_name),ios,err_message,&
      'Options module could not read from the options configuration file')
else
   print*,'Warning: The required configuration file containing options &
      (options.nml) does not exist. The inbuilt options will be &
      used instead.'
endif
!---------------------------------------

end associate

end subroutine load_options

コンパイラは、option1option2、 ... が宣言されていない ( (iFort) error #6404: This name does not have a type, and must have an explicit type. [OPTION1]) と文句を言います。

namelist コンストラクトの説明から ( https://software.intel.com/sites/products/documentation/doclib/stdxe/2013/composerxe/compiler/fortran-mac/GUID-EAC90ABA-859A-4745-B9FC-B8D66B5B6FF0. htm ) 私はそれを読みました

var-list 内の各変数は、USE またはホスト関連付けによってアクセスする必要があります

thisの仮引数と同様に、ここではそうですintent(inout)。利用組合じゃないの?

なにが問題ですか?同じものを別の場所で何度も宣言する必要がないようにする回避策はありますか?

(たとえば、構造を使用するのではなく、モジュールをプライベートとして宣言し、ルーチンの最後にoption1コピーすることは機能しますが、後でオプションを追加するときに省略されにくいものを好むでしょう)thisload_optionsassociate

コメントをお寄せいただきありがとうございます。

PS: 投稿する直前に、この質問を見つけました。コードは私がやりたいことをやっているように見えますが、unit型の定義を見なければ、それが何をしているのか理解できません。

EDIT1: Vladimir のコメントのフォローアップ 今、私は何が起こっているのかをよく理解しています。私がリンクした質問では、作成者はthis個々のフィールドではなくポインターを使用しています。これを機能させることができれば、これが私の好ましいオプションです。私が試したとき、コンパイラは名前リスト宣言で問題ありませんでしたが、入力ファイルからの読み取りを拒否しました

エラー #5498: 割り当て可能またはポインター構造型フィールドには、ユーザー定義の I/O プロシージャが必要です。read(111,NML=options_nml,iostat=ios,iomsg=err_message)

そのような I/O 手順がどのように見えるかについて何か提案はありますか? 名前リスト宣言に派生型(またはそれへのポインター)を追加できる場合、入力ファイル内の変数を参照する必要があり、それthis%option1がそれであると想定します。ここで、インテルのスティーブ・ライオネルがこの見解を支持している別の議論を見つけました。

Fortran 標準では、namelist オブジェクト リストで「変数名」のみが許可されます。ただし、名前リストに T を入れて、名前リスト入力で T%I を参照することはできます (出力に表示されます)。

しかし、コンパイラはファイルを見ることさえせずに不平を言います。

EDIT2:上記のコードで変更したこと(最初の編集でコンパイラエラーにつながる)は次のとおりです。

class(opts), intent(inout), target :: THIS
TYPE(opts), POINTER :: THIS_NML

namelist /options_nml/ THIS_NML
THIS_NML => THIS

関連構文が削除され、元の名前リスト宣言が削除されました。ブロック内のreadステートメントでエラーが発生しました。if (file_exists)そこで私がしたことは、namelist 宣言で構造体へのポインターを使用することでした。それだけでした。

4

1 に答える 1