一般化座標(ユーザー定義座標)
FreeFlexの一つの大きな特徴は、ユーザーが独自に一般化座標を使用して、その値やその上の自由エネルギー面を計算できることにある。座標については、coord_struct構造体が管理しており、その中でとくにユーザー独自の定義した座標はspcoord_struct構造体が管理している。現在、ユーザー定義の座標としては、
- X, Y, Z --- 任意の2つのサイトまたは重心間のX, Y, Z座標の差
- VEC_XYZ --- 2つのサイトまたは重心間の変位ベクトル (X, Y, Z)。多次元spcoordのテスト用。
- R --- 2点間の距離。
- WATFING --- water finger座標
- DE2 --- 電子移動前後のエネルギー差。
などがサポートされている。ユーザー定義の新たな座標の追加の手順も確立されており、それは4-6 を参照のこと。
本章では、4-1 にユーザー定義座標Z, WATFINGの利用のしかたを述べる。4-2 その他の一般化座標の詳細は、&spcoord を参照のこと。
以降はcoord_struct構造体やその関連の説明であり、ユーザー定義座標を追加する際には知っておく必要がある。
ネームリスト
ユーザー定義の座標ZまたはWATFINGを使用するために新たに必要となるネームリストは、&addCOM と &spcoord である
&addCOM
&addCOM condition = “OW HW” /
のように、対象のサイトを指定して行える。conditionで使用できる文字列の形式は、4-3 節で与えたget_site_list に従う。 複数の重心を追加する場合は、それぞれを指定するネームリスト&addCOMを複数書けばよい。さらなる説明は、&addCOM を参照。
&spcoord
ユーザー指定座標の利用はnamelistファイルに
&spcoord condition = “Z 1 2” /
のように “keyword options” の形で指定をすることにより行われる。複数追加する場合は、それぞれを指定する&spcoordを複数書く。さらなる説明は、&spcoord を参照。
使用できるキーワードと対応するオプションの一覧
Keyword Options
Z nCOM1 nCOM2 :重心番号nCOM1とnCOM2の間のz方向の距離。
WATFING nCOM1 nCOM2 wcorr :water finger を射影した座標。
nCOM1: 水分子全体の重心番号
nCOM2: 油相分子の位置
wcorr: 水とイオンのサイズの違いを補正するパラメータ 「もっと詳しい説明」
coord_struct
一般に座標情報を管理する構造体で、通常のサイトやそれらのグループの重心のデカルト座標など(coord_core_structで管理)に加えて、ユーザー定義の座標(spcoord_structで管理)を含む。 座標情報を保持するほか、周期境界条件を考慮した重心や距離を計算するためのプロシージャ、サイト番号を検索するプロシージャ、座標データの更新に関わるプロシージャも含んでいる。
実際には coord_core_struct の拡張構造体になっており、coord_struct%x 等の形の呼び出しで、coord_core_struct 中の x を取得する形を取っている。 ユーザー定義座標以外についての情報やプロシージャは coord_core_struct により管理されているので詳細は次節を参照にすること。 このような形式になっているのは、
coord_struct ------> coord_core_struct
└--> spcoord_struct --┘
のように spcoord_struct においてもcoord_core_structを使用できるようにするためである。 つまり、coord_struct のコンパイルにはspcoord_struct が必要で、かつspcoord_struct のコンパイルにはcoord_struct が必要という相互依存の状況となり、コンパイルが不可能になってしまうのを防ぐためである。
座標や速度の更新後は x2COM 等のプロシージャによりサイトの情報と重心の情報を同期する必要があるのでその点も注意すること。
保持する情報
親構造体coord_core_structの中のサイトや重心の座標などの情報に加えて、以下のユーザー定義の座標の情報をもつ。 <source lang="fortran">
integer :: nspcoord !!! ユーザー定義の座標の数 type(spcoord_struct) :: spcoord(1:nspcoord)
</source> ユーザー定義の座標の情報。coord_struct%spcoord(1)%q 等でspcoord_struct内の情報やプロシージャを取り出せる。
付属するプロシージャ
<source lang="fortran">subroutine read_spcoord(filename)</source>
ユーザー定義の座標についてのネームリスト &spcoord(4-1章参照)を読み込むサブルーチン。
<source lang="fortran">subroutine reallocate_spcoord(n)</source>
ユーザー定義の座標の配列 spcoord をリアロケートするサブルーチン。 (減らす方も考えるか?? n < n_ )
<source lang="fortran">procedure :: update_spcoord_q()</source> spcoord 全部の位置の更新を行うサブルーチン。実際の操作はspcoord_core/ 以下で定義される。詳しくは4-6 章、4-7 章を参照。
<source lang="fortran">procedure :: update_spcoord_v() </source> spcoord 全部の速度の更新を行うサブルーチン。実際の操作はspcoord_core/ 以下で定義される。詳しくは4-6 章、4-7 章を参照。
<source lang="fortran">
procedure :: calculate_dxdq !!! (id,dxdq)
</source>
dxdq を計算するサブルーチン。
<source lang="fortran">
integer,intent(in) :: id(1:n) !!! spcoord の番号 REAL8,intent(out) :: dxdq(1:3,1:nsite,1:n)
</source>
id で指定された座標以外が直交する場合の 。
により計算される。
coord_core_struct
サイトおよび重心の座標情報を管理する構造体。 coord_struct の拡張元として使われる。 以下、座標、速度、質量の単位は、特に指定がない限りSI単位系で与える。
保持する情報
- サイトの情報
<source lang="fortran">
integer :: nsite !!! サイト数 character(len=:), allocatable :: site_name(:) !!! サイト名 (1:nsite) REAL8, allocatable :: x(:,:) !!! 各サイトのデカルト座標 (1:3, 1:nsite) REAL8, allocatable :: v(:,:) !!! 各サイトの速度 (1:3, 1:nsite) REAL8, allocatable :: m(:) !!! 各サイトの質量 (1:nsite)
</source>
- 重心の情報
<source lang="fortran">
integer :: nCOM !!! 重心の数 !character(len=:), allocatable :: COM_name(:) 重心を作るグループの名前 (1:nCOM) REAL8, allocatable :: xCOM(:,:) !!! 各重心の位置 (1:3, 1:nCOM) REAL8, allocatable :: vCOM(:,:) !!! 各重心の速度 (1:3, 1:nCOM) REAL8, allocatable :: mCOM(:) !!! 各重心の質量 (1:nCOM)
</source>
- 系の情報
<source lang="fortran">
REAL8 :: lbox(1:3) !!! 系の x, y, z 方向の長さ
</source>
- サイトと重心の対応表
<source lang="fortran">
type(site_table_struct), private, allocatable :: site(:) !!! (1:nsite)
</source> サイト番号から重心番号を得るのに使用する。
coord_struct%site(1)%naffl でサイト1が所属する重心グループの数、
coord_struct%site(2)%COM_id(3) でサイト2 が所属する3番目の重心グループの番号を得ることができる。4-4 章を参照。
<source lang="fortran">
type(COM_table_struct),private,allocatable :: COM(:) !!! (1:nCOM)
</source> 重心番号からサイト番号、及び(msファイルのSITE_DATA 3列目で指定された)グループ番号を得るのに使用する。 具体的には、
coord_struct%COM(1)%nsite で重心1に含まれるサイトの数、
coord_struct%COM(2)%site_id(3) で重心2 に含まれる3番目のサイトの番号を得ることができる。
また、coord_struct%COM(1)%nCOM で重心1に含まれるグループ番号の数(グループを構成するサイトがすべて含まれるもののみを数える)、
coord_struct%COM(2)%COM_id(3) で重心2 に含まれる3番目のグループ番号
を得ることができる。4-5 章を参照。
付属するプロシージャ
- 基本設定で使用されるプロシージャ
<source lang="fortran"> subroutine init(x,v,m,lbox,nCOM,site_name) </source> 初期設定を行うサブルーチン。引数として読み込んだ変数を、coord_core_struct構造体内に保存する。 <source lang="fortran">
REAL8, intent(in) :: x(1:3,1:nsite) !!! サイトの座標 REAL8, intent(in) :: v(1:3,1:nsite) !!! サイトの速度 REAL8, intent(in) :: m(1:nsite) !!! サイトの質量 REAL8, intent(in) :: lbox(1:3) !!! 系のサイズ integer, intent(in) :: nCOM !!! 暫定的なCOMの数 character(len=*), intent(in) :: site_name(1:nsite) !!! サイトの名前
</source>
- 重心の設定で使用されるプロシージャ
<source lang="fortran"> integer function addCOM(site_id) return(n) </source> 新しい重心を登録する関数。サイト番号のセットsite_idを読み込んで、登録した重心の番号を返す。登録数が init で指定した nCOM より大きくなる場合、自動で配列のリアロケーションが行われる。配列のリアロケーションはメモリ離散化につながるので多用は厳禁。 <source lang="fortran">
integer, intent(in) :: site_id(1:COM%nsite) !!! サイト番号のリスト
</source>
<source lang="fortran">
subroutine reallocate_COM(nCOM)
</source>
重心に関わる配列をリアロケートするサブルーチン。多用は厳禁。
<source lang="fortran">
integer,intent(in) :: nCOM !!! 新しい配列サイズ
</source>
<source lang="fortran">
subroutine read_addCOM(filename)
</source>
新しい重心を定義するネームリスト &addCOM を読み込むサブルーチン。ファイル名filenameのファイル中に置かれた&addCOMを読む。&addCOMの形式は0節を参照。
<source lang="fortran">
character(len=*), intent(in) :: filename
</source>
- 同期を行うプロシージャ
<source lang="fortran"> subroutine x2COM( [COM_id] ) </source>
重心位置の更新を行うサブルーチン。COM_idが指定された場合はそのCOMについてのみ更新が行われ、そうでない場合はこの構造体中の1~nCOMのすべての重心が更新される(以下同様)。 <source lang="fortran">
integer :: COM_id !!! 重心の番号
</source>
<source lang="fortran"> subroutine v2COM( [COM_id] ) : !!! 重心速度の更新を行うサブルーチン。 subroutine COM2x( [COM_id] ) : !!! サイト位置の更新を行うサブルーチン。 subroutine COM2v( [COM_id] ) : !!! サイト速度の更新を行うサブルーチン。 </source> 上のCOM2x, COM2vは、重心が動いたときにサイト位置/速度を一様に動かす操作。COM_idを指定しない場合、2つ以上の重心に属するサイトがあって、それらの重心が別個に動くと、そのサイトの動きが破綻することに注意。そのためできるだけCOM_idを指定して重心を個々に動かすことを推奨する。
- 距離や重心計算を行うプロシージャ
<source lang="fortran"> function calc_distance(x1, x2) result(x) </source> 周期境界を考慮した座標間距離ベクトル(x1-x2)を計算する関数 <source lang="fortran">
REAL8, intent(in) :: x1(1:3), x2(1:3) REAL8 :: x(1:3)
</source>
<source lang="fortran"> function calc_xCOM(site_id) result(xCOM) </source> 周期境界を考慮した重心を計算する関数。COMが定義されていない場合に用いる。(what?) <source lang="fortran">
integer, intent(in) :: site_id(:) REAL8 :: xCOM(1:3)
</source>
<source lang="fortran"> function calc_vCOM(site_id) result(vCOM) </source> 重心の速度を計算する関数。COMが定義されていない場合に用いる。(what?) <source lang="fortran">
integer, intent(in) :: site_id(:) REAL8 :: vCOM(1:3)
</source>
<source lang="fortran"> function calc_mCOM(site_id) result(mCOM) </source> 重心の質量を計算する関数 <source lang="fortran">
integer, intent(in) :: site_id(:) REAL8 :: mCOM
</source>
<source lang="fortran"> subroutine COM2x_core(COM_id) subroutine COM2v_core(COM_id) </source> 重心情報からサイト情報を得る計算のコア部分。それぞれCOM2x, COM2v内から呼び出される。
- 結合情報やサイト名等の情報を処理するプロシージャ
<source lang="fortran"> subroutine get_site_list(condition, list) </source> 入力されたサイト情報から、サイト番号のリストを得る。 <source lang="fortran">
character(len=*), intent(in) :: condition integer, intent(out), allocatable :: list(:)
</source>
conditionで指定されるサイト情報には、以下の3通りのフォーマットが許される。
"OW" → サイト名 "OW" で指定した全サイト "1 2 3" → サイト番号 1,2,3 のサイト "1:100" → サイト番号 1 から 100 までのサイト
これらはスペースで区切って組み合わせが許される。例えば、”OW 1 2 3:8” など。
***個々のワードは1024字を超えないこと。
site_table_struct
サイト番号から重心番号を得るために使用する構造体。モジュールcoord_core_module内のprivateで定義され、coord_core_struct内で参照される。0節「サイトと重心の対応表」を参照。
保持する情報
<source lang="fortran"> integer :: naffl !!! 所属する重心グループの数
integer :: COM_id(1:naffl) !!! 所属する重心の番号のリスト
</source>
付属するプロシージャ
<source lang="fortran"> subroutine addCOM(COM_id) </source> 新しい重心番号をサイト番号と対応付ける。 <source lang="fortran">
integer, intent(in) :: COM_id !!! 追加する重心番号
</source>
COM_table_struct
重心番号からサイト番号、及び(msファイルのSITE_DATA 3列目で指定される)グループ番号を得るために使用する構造体。モジュールcoord_core_module内のprivateで定義され、coord_core_struct内で参照される。0節「サイトと重心の対応表」を参照
保持する情報
<source lang="fortran">
integer :: nsite !!! 指定された重心に含まれるサイトの数 integer :: site_id(1:nsite) !!! 含まれるサイトの番号のリスト integer :: nCOM !!! 重心に含まれているグループの数。グループを構成するサイトがすべて含まれるもののみを数える。 integer :: COM_id(1:nsite) !!! そのグループ番号のリスト。 !!!
</source>
spcoord_struct
ユーザー定義の座標の情報を管理する構造体。spcoord_struct%q 等でユーザー定義の座標の値等を知ることができる。2015/8/7現在、ユーザー定義の座標としてZとWATFINGの2種類がサポートされているが、ユーザー独自の座標を容易に追加できる手順が確立されている。
spcoord_structのプロシージャは、基本的に抽象構造型 spcoord_core_struct のラッパーになっている。各ユーザー定義座標(xxx)は、この抽象構造型をユーザー定義の拡張構造体spcoord_xxx_structで上書きする形で定義される。 これについてはspcoord_core_struct を参照すること。
新しい座標 xxx を追加するには、
1.spcoord_core/ ディレクトリ内にファイルxxx.F を用意して、拡張構造体 spcoord_xxx_struct を記述する。
2.spcoord.F中のサブルーチン spcoord_struct%setting 内の分岐を記述する。
<source lang="fortran">
... type(spcoord_xxx_struct),pointer :: xxx ... case(“XXX”) allocate(xxx) self%core => xxx ...
</source> 3.Makefile 中のSPCOORD_CORE変数にファイル名を追加する。 <source lang="fortran">
... SPCOORD_CORE := z.F watfing.F xxx.F ...
</source> の3つの操作が必要になる。 2, 3については、例示のようにプログラム中に数行機械的に書き加えるだけなので、各プログラムを参照すること。
保持する情報
<source lang="fortran">
REAL8 :: q !!! ユーザー定義の座標の値 REAL8 :: v !!! ユーザー定義の速度の値
</source>
<source lang="fortran">
integer :: nsite !!! ユーザー定義の座標に関わるサイトの数 integer,allocatable :: site_id(:)
</source> ユーザー定義の座標に関わるサイトの番号 (1:nsite) <source lang="fortran">
REAL8, allocatable :: dqdx(:,:) !!! q のサイト座標微分 (1:3,1:nsite)
</source>
<source lang="fortran">
class(spcoord_core_struct), private, pointer, :: core
</source> spcoord 本体部分。 実際の処理はこの中で行っている。 詳しくは次節参照。
付属するプロシージャ
<source lang="fortran"> subroutine setting(coord, condition) </source> ユーザー定義の座標の初期設定を行うサブルーチン。 実際にここで行うのは座標の種類に応じた変数のアロケーションのみで、詳細はspcoord_core/ 以下のファイルで設定する。 <source lang="fortran">
class(coord_core_struct) :: coord character(len=*), intent(in) :: condition
</source> 条件設定のための文字列。ユーザー定義の座標の種類とそのオプションを与える。0節参照。
<source lang="fortran"> subroutine update_q(coord) </source> 座標の更新を行うサブルーチン。 この関数はcoord_struct%update_spcoord によって呼び出され、基本的には直接使用しない。 <source lang="fortran">
class(coord_core_struct) :: coord
</source>
<source lang="fortran"> subroutine update_v(coord) </source> 速度の更新を行うサブルーチン。 この関数はcoord_struct%update_spcoord によって呼び出され、基本的には直接使用しない。 <source lang="fortran"> class(coord_core_struct) :: coord </source>
- 拘束計算関連のプロシージャ
<source lang="fortran"> subroutine update_q_constr(coord) </source> 拘束計算における座標の更新を行うサブルーチン。 core%update_q_constr のラッパー。 <source lang="fortran">
class(coord_core_struct) :: coord
</source>
spcoord_core_struct
ユーザー定義の座標を処理するための抽象 (abstract) 構造型。 ここで定義されている deferred 指定されたプロシージャを上書きした拡張構造型をspcoord_core/ ディレクトリ以下に作成することで新しい座標を定義することができる。 プロシージャは引数を含めて全ての拡張構造体で一致させる必要があるため、引数の変更やプロシージャの追加・変更は慎重に行うこと。
*** 重心を使用する場合は、0節の x2COM(COM_id) 等を行って座標と同期されている必要があることに注意。
付属するプロシージャ
<source lang="fortran"> subroutine init(coord, condition) </source> 座標の条件を指定した文字列 condition をもとに初期設定を行うサブルーチン。 <source lang="fortran"> class(coord_core_struct) :: coord
character(len=*), intent(in) :: condition
</source> 座標の条件を指定した文字列。書式は0節を参照。
<source lang="fortran"> subroutine update_q(coord) </source> 座標の更新を行うサブルーチン <source lang="fortran"> class(coord_core_struct) :: coord </source>
<source lang="fortran"> subroutine update_v(coord) </source> 速度の更新を行うサブルーチン <source lang="fortran"> class(coord_core_struct) :: coord </source>
<source lang="fortran"> subroutine get_site_id(site_id) </source> 座標に関連するサイトの番号のリストを返すサブルーチン。 リストには同じ番号が複数回現れる可能性があるので注意すること。【どういう意味か?】 アロケーションも同時に行われる。 <source lang="fortran"> integer, allocatable, intent(out) :: site_id(:) </source>
<source lang="fortran"> REAL8 function get_q () result(q) </source> 座標の値を返す関数。
<source lang="fortran"> REAL8 function get_v() result(v) </source> 速度の値を返す関数。
<source lang="fortran">
subroutine get_dqdx(dqdx)
</source>
ユーザー指定座標のサイト座標微分を返す関数。
<source lang="fortran">
REAL8, intent(out) :: dqdx(1:3,1:size(site_id))
</source>
- 拘束計算用のプロシージャ
<source lang="fortran"> subroutine update_q_constr(coord) </source> 拘束計算のための座標、及び dqdx の更新を行うサブルーチン。 通常は update_q と同じものなのでそれを呼び出せばよいが、座標微分に不連続性がある場合は特殊な操作が必要になるため別に用意する。
