<?xml version="1.0"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="ja">
	<id>http://comp.chem.tohoku.ac.jp/mediawiki/index.php?action=history&amp;feed=atom&amp;title=%E6%8B%98%E6%9D%9F%E8%A8%88%E7%AE%97</id>
	<title>拘束計算 - 版の履歴</title>
	<link rel="self" type="application/atom+xml" href="http://comp.chem.tohoku.ac.jp/mediawiki/index.php?action=history&amp;feed=atom&amp;title=%E6%8B%98%E6%9D%9F%E8%A8%88%E7%AE%97"/>
	<link rel="alternate" type="text/html" href="http://comp.chem.tohoku.ac.jp/mediawiki/index.php?title=%E6%8B%98%E6%9D%9F%E8%A8%88%E7%AE%97&amp;action=history"/>
	<updated>2026-05-27T05:56:46Z</updated>
	<subtitle>このウィキのこのページに関する変更履歴</subtitle>
	<generator>MediaWiki 1.36.2</generator>
	<entry>
		<id>http://comp.chem.tohoku.ac.jp/mediawiki/index.php?title=%E6%8B%98%E6%9D%9F%E8%A8%88%E7%AE%97&amp;diff=1087&amp;oldid=prev</id>
		<title>Hirano: ページの作成:「　一般化座標を４  章のようにユーザー定義して与えた際に、その座標を拘束した計算が一般的に可能である。  == ネームリ…」</title>
		<link rel="alternate" type="text/html" href="http://comp.chem.tohoku.ac.jp/mediawiki/index.php?title=%E6%8B%98%E6%9D%9F%E8%A8%88%E7%AE%97&amp;diff=1087&amp;oldid=prev"/>
		<updated>2026-05-26T03:12:04Z</updated>

		<summary type="html">&lt;p&gt;ページの作成:「　一般化座標を&lt;a href=&quot;/mediawiki/index.php?title=%EF%BC%94_%E7%AB%A0&amp;amp;action=edit&amp;amp;redlink=1&quot; class=&quot;new&quot; title=&quot;４ 章 (存在しないページ)&quot;&gt;４  章&lt;/a&gt;のようにユーザー定義して与えた際に、その座標を拘束した計算が一般的に可能である。  == ネームリ…」&lt;/p&gt;
&lt;p&gt;&lt;b&gt;新規ページ&lt;/b&gt;&lt;/p&gt;&lt;div&gt;　一般化座標を[[４  章]]のようにユーザー定義して与えた際に、その座標を拘束した計算が一般的に可能である。&lt;br /&gt;
&lt;br /&gt;
== ネームリスト ==&lt;br /&gt;
　拘束計算に関するネームリストは、&amp;amp;constraint2, &amp;amp;addconstr である。その他にユーザー定義座標を与えるためのネームリスト &amp;amp;addCOM や &amp;amp;spcoord などが必要であるが、これは[[４-１]]  節を参照のこと。&lt;br /&gt;
　ネームリストの仕様は、&amp;amp;constraint2 ([[３-１２]]  ) および &amp;amp;addconstr （[[３-１３]]  ）を参照すること。&lt;br /&gt;
&lt;br /&gt;
　FreeFlex で拘束計算を行うにはネームリストファイルに、&lt;br /&gt;
&lt;br /&gt;
 === input.nml =================================================================================&lt;br /&gt;
   .&lt;br /&gt;
   .&lt;br /&gt;
   .&lt;br /&gt;
 &amp;amp;addCOM&lt;br /&gt;
   condition = &amp;quot;OW HW&amp;quot;&lt;br /&gt;
 /&lt;br /&gt;
 &lt;br /&gt;
 &amp;amp;spcoord&lt;br /&gt;
   condition = &amp;quot;Z 877 878&amp;quot;&lt;br /&gt;
 /&lt;br /&gt;
 !!! Na+ の重心が 877。878 は水全体の重心。&lt;br /&gt;
 &lt;br /&gt;
 &amp;amp;addconstr&lt;br /&gt;
   condition = &amp;quot;SPCOORD 1 20.0d-10 1.0d-10&amp;quot;&lt;br /&gt;
 /&lt;br /&gt;
 ================================================================================================&lt;br /&gt;
&lt;br /&gt;
のように &amp;amp;addCOM, &amp;amp;spcoord, &amp;amp;addconstr を足してやればよい。上の[[２-５節のチュートリアル]](sample/tutorial/05) を参照。この例では、重心877番と重心878番のz方向の距離を20 Åに固定されたトラジェクトリを得ることができる。&lt;br /&gt;
&lt;br /&gt;
[[ファイル:Z-condition-fixed_system1.jpg|center]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== 計算原理 ==&lt;br /&gt;
　SHAKE-RATTLE法の考え方に従い、 k 番目の拘束だけを考えこれを満足させることを考える。 この時、時間発展として&lt;br /&gt;
{{NumBlk|::|&lt;br /&gt;
&amp;lt;math&amp;gt;\begin{align}&lt;br /&gt;
\mathbf{v}_i' (t+\frac{1}{2} \Delta t)&amp;amp;=\mathbf{v}_i (t)+\frac{\Delta t}{2m_i} \mathbf{F}_i (t)\\&lt;br /&gt;
\mathbf{x}_i' (t+\Delta t)&amp;amp;=\mathbf{x}_i (t)+\Delta t \mathbf{v}_i' (t+\frac{1}{2} \Delta t)\\&lt;br /&gt;
(*) \quad&lt;br /&gt;
\mathbf{x}_i (t+\Delta t)&amp;amp;=\mathbf{x}_i' (t+\Delta t)+\frac{\gamma_k^x (t)}{m_i}   \frac{\partial g_k (\{ \mathbf{x}_i (t)\}) } {\partial \mathbf{x}_i }\\&lt;br /&gt;
(*) \quad&lt;br /&gt;
\mathbf{v}_i (t+\frac{1}{2} \Delta t)&amp;amp;=\mathbf{v}_i' (t+\frac{1}{2} \Delta t)+\frac{\gamma _k^x (t)}{m_i \Delta t}  \frac{\partial g_k (\{\mathbf{x}_i (t)\})}{\partial \mathbf{x}_i } \\&lt;br /&gt;
\mathbf{v}_i' (t+\Delta t)&amp;amp;=\mathbf{v}_i (t+\frac{1}{2} \Delta t)+\frac{ \Delta t}{2m_i} \mathbf{F}_i (t+\Delta t) \\&lt;br /&gt;
(*) \quad&lt;br /&gt;
\mathbf{v}_i (t+\Delta t)&amp;amp;=\mathbf{v}_i' (t+\Delta t)+\frac{\gamma_k^v (t+\Delta t)}{m_i}   \frac{\partial g_k (\{\mathbf{x}_i (t+\Delta t)\})}{\partial \mathbf{x}_i }&lt;br /&gt;
\end{align}&amp;lt;/math&amp;gt;|{{EquationRef|1}}}}&lt;br /&gt;
&lt;br /&gt;
を使用する。&amp;lt;math&amp;gt; \gamma_k^x, \gamma_k^v&amp;lt;/math&amp;gt; は、時間発展後の座標が拘束条件を満たすという条件&lt;br /&gt;
{{NumBlk|::|&lt;br /&gt;
&amp;lt;math&amp;gt;(*) \quad&lt;br /&gt;
g_k \left( \{\mathbf{x}_i (t)\}, \{ \mathbf{x}_i' (t+\Delta t)\},\gamma_k^x \right)=0&lt;br /&gt;
&amp;lt;/math&amp;gt;|{{EquationRef|2}}}} &lt;br /&gt;
&lt;br /&gt;
{{NumBlk|::|&lt;br /&gt;
&amp;lt;math&amp;gt;(*) \quad&lt;br /&gt;
\frac{dg_k}{dt} \left(\{\mathbf{x}_i (t+\Delta t)\},\{\mathbf{v}_i' (t+\Delta t)\},\gamma_k^v \right)=0&lt;br /&gt;
&amp;lt;/math&amp;gt;|{{EquationRef|3}}}}&lt;br /&gt;
&lt;br /&gt;
を解くことにより求める。 拘束が複数存在する場合には上記の手順を繰り返すことにより全ての拘束条件を満たす構造を求める。 収束判定は&lt;br /&gt;
&amp;lt;math&amp;gt;(g_k )^2&amp;lt;(tolerance)^2,\left( \frac{dg_k}{dt} \right)^2&amp;lt;\left( \frac{tolerance}{\Delta t} \right)^2 &amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
により行っている。拘束の種類によらず同じ tolerance を用いる為 &amp;lt;math&amp;gt;g_k&amp;lt;/math&amp;gt; は無次元に取る必要がある。&lt;br /&gt;
&lt;br /&gt;
　実際の計算では、拘束条件によって値が変化する (*) の部分は constraint2_core_struct の拡張構造体が担い、その他の拘束条件の種類によらず形が変わらない部分は constraint2_struct が担う。&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== SHAKE法による補正前 &amp;lt;math&amp;gt;|g_k |&amp;lt;/math&amp;gt; が大きい場合 ===&lt;br /&gt;
　初期構造が固定したい状態と離れている場合、拘束計算が収束しない可能性がある。 これに対処するため、SHAKE計算のループの前に&amp;lt;math&amp;gt;(g_k )^2&amp;gt; (threshold)^2&amp;lt;/math&amp;gt; かどうかの判定を行い、&amp;lt;math&amp;gt;|g_k |&amp;lt;/math&amp;gt;が threshold よりも大きい場合、拡張構造体内のchange_condition(g) サブルーチンによって拘束条件を一時的に変更する。 具体的な例として、&amp;lt;math&amp;gt;g = q(\{ x_i \} ) - q_0&amp;lt;/math&amp;gt; の場合を考えると、&amp;lt;math&amp;gt;q_0&amp;lt;/math&amp;gt; を &amp;lt;math&amp;gt;q_0' = q - sign(g) * d &amp;lt;/math&amp;gt; (d は適当な定数） に変更することになる。 なお、変更時には警告メッセージを出力する。 SHAKE 計算終了後、拘束条件を元に戻すサブルーチン restore_condition() を実行し変更を元に戻す。&lt;br /&gt;
&lt;br /&gt;
== プログラムの構造と拘束条件の追加 ==&lt;br /&gt;
　MD計算の際にどのような設定を行うかは[[５-４  章]]及び[[チュートリアル２-５]]  を参照すること。 ここではソースコードの構造について述べる。&lt;br /&gt;
&lt;br /&gt;
　拘束関連のプログラムの構造は以下のようになっている。&lt;br /&gt;
&lt;br /&gt;
[[ファイル:5-3_program_struct.jpg|center|600px]]&lt;br /&gt;
&lt;br /&gt;
　拘束計算のコアとなる処理はconstraint2_core/ 以下のファイルで行っている。 このディレクトリ下にはconstraint_core.F に定義されているconstraint_core_struct の拡張構造体が置かれている。 この拡張構造体は、少なくとも&lt;br /&gt;
&amp;lt;source lang=&amp;quot;fortran&amp;quot;&amp;gt;&lt;br /&gt;
    subroutine init(condition)&lt;br /&gt;
    !!!&lt;br /&gt;
    !!! 拘束条件を指定した文字列 condition から、&lt;br /&gt;
    !!! 必要なパラメータを取り出すサブルーチン&lt;br /&gt;
    !!!&lt;br /&gt;
      character(len=*), intent(in) :: condition&lt;br /&gt;
      !!!&lt;br /&gt;
      !!! 拘束条件を指定した文字列&lt;br /&gt;
      !!!&lt;br /&gt;
    endsubroutine&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;fortran&amp;quot;&amp;gt;&lt;br /&gt;
    subroutine SHAKE (coord,dt)&lt;br /&gt;
    !!!&lt;br /&gt;
    !!! 距離に関する拘束の式（テキスト式(2)）を解き、&lt;br /&gt;
    !!! coord に新しい座標を返すサブルーチン&lt;br /&gt;
    !!!&lt;br /&gt;
      type(coord_struct), intent(inout) :: coord&lt;br /&gt;
      !!!&lt;br /&gt;
      !!!  input: 拘束考慮前の座標&lt;br /&gt;
      !!!  output: 拘束考慮後の座標&lt;br /&gt;
      !!!&lt;br /&gt;
      !!!   REAL8, intent(in) :: dt&lt;br /&gt;
      !!!     時間刻み&lt;br /&gt;
      !!!&lt;br /&gt;
    endsubroutine&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;fortran&amp;quot;&amp;gt;&lt;br /&gt;
    subroutine RATTLE(coord)&lt;br /&gt;
    !!!&lt;br /&gt;
    !!! 速度に関する拘束の式(3)を解き、&lt;br /&gt;
    !!! coord に新しい速度を返すサブルーチン&lt;br /&gt;
    !!!&lt;br /&gt;
      type(coord_struct), intent(inout) :: coord&lt;br /&gt;
      !!!&lt;br /&gt;
      !!!  input: 拘束考慮前の座標&lt;br /&gt;
      !!!  output: 拘束考慮後の座標&lt;br /&gt;
      !!!&lt;br /&gt;
    endsubroutine&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;fortran&amp;quot;&amp;gt;&lt;br /&gt;
    REAL8 function g(coord)&lt;br /&gt;
    !!!&lt;br /&gt;
    !!! 拘束条件を規定する式 g を返す関数&lt;br /&gt;
    !!! ( g = 0 のとき拘束条件が満たされる）&lt;br /&gt;
    !!!&lt;br /&gt;
    !!!   type(coord_struct), intent(inout) :: coord&lt;br /&gt;
    !!!&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;fortran&amp;quot;&amp;gt;&lt;br /&gt;
    REAL8 function dgdt (coord)&lt;br /&gt;
    !!!&lt;br /&gt;
    !!! dg/dt を返す関数&lt;br /&gt;
    !!! ( dg/dt = 0 のとき拘束条件が満たされる）&lt;br /&gt;
    !!!&lt;br /&gt;
    !!!   type(coord_struct), intent(inout) :: coord&lt;br /&gt;
    !!!&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;fortran&amp;quot;&amp;gt;&lt;br /&gt;
    subroutine change_condition(g,coord,oldcoord)&lt;br /&gt;
    !!!&lt;br /&gt;
    !!! 系の構造が拘束条件と大きく離れている場合の処理&lt;br /&gt;
    !!!&lt;br /&gt;
    !!! REAL8,intent(in) :: g    !!! 拘束条件の式の値&lt;br /&gt;
    !!! type(coord_struct),intent(inout) :: coord,oldcoord&lt;br /&gt;
    !!!   時間発展前後の座標&lt;br /&gt;
    !!!&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;fortran&amp;quot;&amp;gt;&lt;br /&gt;
    subroutine restore_condition()&lt;br /&gt;
    !!!&lt;br /&gt;
    !!! change_condition で変更した値を元に戻すサブルーチン&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
の7つのプロシージャを定義する必要がある。 その他追加のパラメータや変数が必要な場合は読み込み用のサブルーチンを適宜作成する。 なお、これらのプロシージャの実行によって座標や速度が更新される場合、その実行後に重心やユーザー定義座標を用いる場合には、それらの更新も別途行って同期する必要があることに注意すること。&lt;br /&gt;
&lt;br /&gt;
　実際の追加には拡張構造体の作成のほか、constraint2_condition.F 中で分岐処理を追加する必要がある。select case 文に新しい case として、&lt;br /&gt;
&amp;lt;source lang=&amp;quot;fortran&amp;quot;&amp;gt;&lt;br /&gt;
      case(&amp;quot;SAMPLE&amp;quot;)&lt;br /&gt;
        allocate(sample)&lt;br /&gt;
        self%core =&amp;gt; sample&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
のようなものを追加するだけなのでソースを参考にしてほしい。&lt;br /&gt;
&lt;br /&gt;
== 拘束条件の指定と実際の計算式 ==&lt;br /&gt;
　MD計算で拘束条件を追加するには、FreeFlexに読み込ませるネームリストファイルに&lt;br /&gt;
&lt;br /&gt;
 &amp;amp;addconstr&lt;br /&gt;
   condition = “keyword options”&lt;br /&gt;
 /&lt;br /&gt;
&lt;br /&gt;
の形で新しい条件を指定すればよい。 また、&amp;amp;constraint2 ネームリストにより拘束計算全体に関わる設定も変更できる。 詳しくは tutorial.docx を見ること。&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== DISTANCE ===&lt;br /&gt;
　拘束条件を指定する文字列として&lt;br /&gt;
 condition = “DISTANCE  i  j  r0  runit  maxmove”&lt;br /&gt;
とした場合、サイト-サイト間距離の拘束を行う。i, j はサイトの番号、r0 は拘束距離（m）を意味する。 また、runit, maxmoveは計算に用いるパラメータで下記の説明の通りである。 これらのパラメータは指定しなくても良く、その場合デフォルトの値として r&amp;lt;sup&amp;gt;unit&amp;lt;/sup&amp;gt;=1 Å,maxmove=0.01 Å が使用される。 &lt;br /&gt;
拘束条件にDISTANCE を指定した際の具体的な拘束条件の式は&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;g=\frac{(\mathbf{x}_i-\mathbf{x}_j )^2-r_0^2}{(r^{unit})^2} =0&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
である。&lt;br /&gt;
&lt;br /&gt;
　上記拘束条件のもとラグランジュ未定乗数を求めると、&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;\begin{align}&lt;br /&gt;
\gamma_k^x &amp;amp;= \frac{ (r^{unit} )^2 \left[ \left\{\mathbf{x}_i' (t+\Delta t)-\mathbf{x}_j' (t+\Delta t) \right\}^2-r_0^2 \right] }&lt;br /&gt;
{ 2 \left( \frac{1}{m_i}+\frac{1}{m_j} \right) \left\{\mathbf{x}_i (t)-\mathbf{x}_j (t) \right\} \cdot \left\{ \mathbf{x}_i' (t+\Delta t)-\mathbf{x}_j' (t+\Delta t) \right\} } \\&lt;br /&gt;
&lt;br /&gt;
\gamma_k^v &amp;amp;= \frac{ (r^{unit} )^2 \left\{ \mathbf{v}_i' (t+\Delta t)-\mathbf{v}_j' (t+\Delta t) \right\} \cdot \left\{ \mathbf{x}_i (t+\Delta t)-\mathbf{x}_j (t+\Delta t) \right\} }&lt;br /&gt;
{ \left( \frac{1}{m_i} +\frac{1}{m_j} \right) \left\{\mathbf{x}_i (t+\Delta t)-\mathbf{x}_j (t+\Delta t) \right\}^2 } \\&lt;br /&gt;
&lt;br /&gt;
\end{align}&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
となる。&lt;br /&gt;
&lt;br /&gt;
　系の構造が拘束条件から大きく外れている場合、&amp;lt;math&amp;gt;r_0&amp;lt;/math&amp;gt; の代わりに&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;r_0'=\sqrt{\left[ \mathbf{x}_i (t)-\mathbf{x}_j (t) \right]^2} -sign (g_k )*maxmove &amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
を用いる。&lt;br /&gt;
&lt;br /&gt;
=== SPCOORD ===&lt;br /&gt;
拘束条件を指定する文字列として&lt;br /&gt;
 condition = “SPCOORD  n  &amp;lt;s&amp;gt;nq&amp;lt;/s&amp;gt;  q0(1:nq)  qunit  maxmove”&lt;br /&gt;
とした場合、ユーザー定義座標の拘束を行う。 nはユーザー定義座標（ネームリストの上から1,2,…となる）の番号、&amp;lt;s&amp;gt;nq は指定したユーザー定義座標の次元数&amp;lt;/s&amp;gt; (※ nq は spcoord_core_struct の関数(get_nq)で設定されるので、ネームリストの指定は不要。)、 q0(1:nq) は拘束値、qunit, maxmove は計算に用いるパラメータである。具体的な拘束条件の式としては、&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;g=\frac{q \left( \{\mathbf{x}_i \} \right)-q_0} {q^{unit}} =0 &amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
を用いる。 ここでユーザー定義座標を q で表記している。この時、&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt; \mathbf{x}_i (t+\Delta t)=\mathbf{x}_i' (t+\Delta t)+\frac{\gamma_k^q} {m_i} \frac{1}{q^{unit} } \frac{\partial q(t)}{\partial \mathbf{x}_i }&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
であるから、&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;\begin{align}&lt;br /&gt;
&amp;amp;\frac{1} {q^{unit} }  \left[ q \left( \left\{ \mathbf{x}_i' (t+\Delta t)+\frac{\gamma_k^q}{m_i} \frac{1}{q^{unit} }  \frac{ \partial q(t)}{\partial \mathbf{x}_i } \right\} \right)-q_0 \right] \\&lt;br /&gt;
&lt;br /&gt;
\approx &amp;amp;\frac{1}{q^{unit} }   \left[q' (t+\Delta t)+\sum_i \frac{ \gamma_k^q}{m_i}   \frac{1}{q^{unit} }  \frac{\partial q(t)}{\partial \mathbf{x}_i } \cdot \frac{\partial q(t+\Delta t)}{\partial \mathbf{x}_i}-q_0 \right]=0&lt;br /&gt;
&lt;br /&gt;
\end{align} &amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;&lt;br /&gt;
\gamma_k^q=-q^{unit} \left[q(t+\Delta t)-q_0 \right] / \sum_i \frac{1}{m_i}  \frac{\partial q(t)} {\partial \mathbf{x}_i }\cdot \frac{\partial q(t+\Delta t)}{\partial \mathbf{x}_i}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
となる。 同様にして速度については、&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;&lt;br /&gt;
\frac{dg_k}{dt}=\frac{1}{q^{unit} }  \sum_i\frac{\partial q}{\partial \mathbf{x}_i}\cdot \mathbf{v}_i=0&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
が拘束条件となる。 従って速度の時間発展が、&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;&lt;br /&gt;
\mathbf{v}_i (t+\Delta t)=\mathbf{v}_i' (t+\Delta t)+\frac{\gamma_k^v}{m_i}   \frac{1}{q^{unit} }   \frac{\partial q(t+\Delta t)}&lt;br /&gt;
{\partial \mathbf{x}_i}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
と表されることから、&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;&lt;br /&gt;
\frac{1}{q^{unit} } \sum_i  \frac{\partial q(t+\Delta t)} {\partial \mathbf{x}_i} \left[ \mathbf{v}_i' (t+\Delta t)+\frac{\gamma_k^v}{m_i}   \frac{1}{q^{unit} }   \frac{\partial q(t+\Delta t)}&lt;br /&gt;
{\partial \mathbf{x}_i} \right] =0&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;&lt;br /&gt;
\gamma_k^v=- \xi^{unit} \sum_i  \frac{\partial q(t+\Delta t)} {\partial \mathbf{x}_i } \cdot \mathbf{v}_i' (t+\Delta t)&lt;br /&gt;
/ \sum_i \frac{1}{m_i} \left[ \frac{\partial q(t+\Delta t)} {\partial \mathbf{x}_i} \right]^2&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
が得られる。&lt;br /&gt;
&lt;br /&gt;
　系の構造が拘束条件から大きく外れている場合、q_0 の代わりに&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;q_0'=q(t)-sign (g_k )*maxmove &amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
を用いる。&lt;br /&gt;
===&amp;lt;math&amp;gt; \frac{ \partial q}{\partial \mathbf{x}_i}&amp;lt;/math&amp;gt; が不連続になる場合の処理 ===&lt;br /&gt;
　water finger 座標等、時間発展やSHAKE法のループ中に注目する粒子の入れ替わりが起こる場合、&amp;lt;math&amp;gt; \frac{ \partial q}{\partial \mathbf{x}_i}&amp;lt;/math&amp;gt; が不連続になる。 &amp;lt;math&amp;gt; \frac{ \partial q(t)}{\partial \mathbf{x}_i}, \frac{ \partial q(t+\Delta t)}{\partial \mathbf{x}_i}&amp;lt;/math&amp;gt; の値として入れ替わり前後の値を用いてしまうと通常のSHAKE法のループが収束する保証はない。 そこでSHAKE計算においては粒子の入れ替わりを無視し、時刻 t+Δt における注目粒子を用いた場合の &amp;lt;math&amp;gt; \frac{ \partial q(t)}{\partial \mathbf{x}_i}&amp;lt;/math&amp;gt; に対応する値を使用することにする。 この処理は、spcoord_core_struct 内に注目粒子を交換せずに &amp;lt;math&amp;gt; \frac{ \partial q(t)}{\partial \mathbf{x}_i}&amp;lt;/math&amp;gt; を更新するサブルーチン update_q_constr(coord) を用意することで、&lt;br /&gt;
&lt;br /&gt;
*constraint2_struct 内のサブルーチン save_oldcoordにおいて時刻 t における座標を oldcoord として保存。&lt;br /&gt;
*constraint2_core_struct 内のサブルーチン SHAKE(coord,oldcoord,dt) において、&lt;br /&gt;
**coord%spcoord(n)%update_q_constr(coord) を実行。&lt;br /&gt;
**coord%spcoord(n)%get_dqdx(dqdx) により&amp;lt;math&amp;gt; \frac{ \partial q(t+\Delta t)}{\partial \mathbf{x}_i}&amp;lt;/math&amp;gt;  を取得。&lt;br /&gt;
**coord%spcoord(n)%update_q_constr(oldcoord) を実行。&lt;br /&gt;
**coord%spcoord(n)%get_dqdx(old_dqdx) により &amp;lt;math&amp;gt; \frac{ \partial q(t)}{\partial \mathbf{x}_i}&amp;lt;/math&amp;gt;  を取得。&lt;br /&gt;
のような処理により実装が可能となる。&lt;br /&gt;
&lt;br /&gt;
=== FREEZE ===&lt;br /&gt;
*古い仕様&lt;br /&gt;
&lt;br /&gt;
　条件を&lt;br /&gt;
 condition = “FREEZE  i”&lt;br /&gt;
とした場合、i 番目の重心グループの位置を固定する。 プログラム内では、位置・速度の補正時に&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;\begin{align}&lt;br /&gt;
\mathbf{x}_i (t+\Delta t)&amp;amp;=\mathbf{x}_i (t) \\&lt;br /&gt;
\mathbf{v}_i (t+\Delta t)&amp;amp;=0&lt;br /&gt;
\end{align}&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
としているだけである。&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
*新しい仕様&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;A&amp;lt;/math&amp;gt; 番目の重心グループの位置を空間固定系に対して固定する。&lt;br /&gt;
ただし単純に重心を空間固定系に対して拘束しようとすると1体の拘束力をかけることとなり、&lt;br /&gt;
内力場でなくなるため重心が移動する問題がある。&lt;br /&gt;
ここではこれを解決する方法として、&amp;lt;math&amp;gt;A&amp;lt;/math&amp;gt; の重心と系全体の重心間に拘束をかけることを考える。&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;A&amp;lt;/math&amp;gt; 番目のグループの質量の和を &amp;lt;math&amp;gt;M_A&amp;lt;/math&amp;gt;、系に含まれる全粒子の質量の和を &amp;lt;math&amp;gt;M&amp;lt;/math&amp;gt; とする。&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;\begin{align}&lt;br /&gt;
M_A = \sum_{i\in A}m_i \\&lt;br /&gt;
M = \sum_i m_i&lt;br /&gt;
\end{align}&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
系の相互作用が内力のみから成る場合、系の重心は空間固定系に対して移動しない。&lt;br /&gt;
従って &amp;lt;math&amp;gt;A&amp;lt;/math&amp;gt; の重心を空間固定系に対して固定したい場合、&lt;br /&gt;
系の重心に対する相対位置 &amp;lt;math&amp;gt;\Delta R&amp;lt;/math&amp;gt; を固定すればこれは達成される。&lt;br /&gt;
このとき拘束条件 &amp;lt;math&amp;gt;g&amp;lt;/math&amp;gt; およびその微分 &amp;lt;math&amp;gt;\partial g/\partial r_i&amp;lt;/math&amp;gt; は、次の式で書ける。&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;\begin{align}&lt;br /&gt;
g &amp;amp;= \frac{\sum_{i\in A}m_ir_i}{M_A} - \frac{\sum_j m_jr_j}{M} - \Delta R \\&lt;br /&gt;
  &amp;amp;= \sum_{i\in A}m_ir_i\Bigl(\frac{1}{M_A} - \frac{1}{M}\Bigr) - \sum_{j\in\bar{A}}m_jr_j \frac{1}{M} - \Delta R = 0&lt;br /&gt;
\end{align} &amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;\begin{align}&lt;br /&gt;
\frac{\partial g}{\partial r_i} =&lt;br /&gt;
\begin{cases}&lt;br /&gt;
m_i\Bigl(\frac{1}{M_A} - \frac{1}{M}\Bigr) &amp;amp; i\in A \\&lt;br /&gt;
-\frac{m_i}{M}                             &amp;amp; i\in \bar{A} \\&lt;br /&gt;
\end{cases}&lt;br /&gt;
\end{align} &amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
拘束をかける前の座標および速度を &amp;lt;math&amp;gt;r_i^0&amp;lt;/math&amp;gt;、&amp;lt;math&amp;gt;v_i^0&amp;lt;/math&amp;gt; とし、&lt;br /&gt;
拘束力による変位を座標および速度に対してそれぞれ &amp;lt;math&amp;gt;\delta r_i&amp;lt;/math&amp;gt;、&amp;lt;math&amp;gt;\delta v_i&amp;lt;/math&amp;gt; とする。&lt;br /&gt;
ここで &amp;lt;math&amp;gt;r_i^0&amp;lt;/math&amp;gt; および &amp;lt;math&amp;gt;v_i^0&amp;lt;/math&amp;gt; は通常の力 &amp;lt;math&amp;gt;-\partial U/\partial r_i&amp;lt;/math&amp;gt; による変位を含むため、&lt;br /&gt;
必ずしも拘束条件は満たされていない。&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;\begin{align}&lt;br /&gt;
r_i &amp;amp;= r_i^0 + \delta r_i \\&lt;br /&gt;
v_i &amp;amp;= v_i^0 + \delta v_i&lt;br /&gt;
\end{align}&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
しかし通常の力が内力のみから構成されるとき、系の重心は初期配置での重心 &amp;lt;math&amp;gt;R_0&amp;lt;/math&amp;gt; に常に固定される。&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;\begin{align}&lt;br /&gt;
\frac{\sum_i m_ir_i^0}{M} = R_0&lt;br /&gt;
\end{align}&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
拘束力による変位は未定乗数 &amp;lt;math&amp;gt;\lambda&amp;lt;/math&amp;gt; を用いて次式で書ける。&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;\begin{align}&lt;br /&gt;
\delta r_i = \lambda\frac{\partial g}{\partial r_i}\frac{(\Delta t)^2}{2m_i} =&lt;br /&gt;
\begin{cases}&lt;br /&gt;
\lambda\Bigl(\frac{1}{M_A} - \frac{1}{M}\Bigr)\frac{(\Delta t)^2}{2} &amp;amp;\equiv \delta r_A &amp;amp; i\in A \\&lt;br /&gt;
-\frac{\lambda}{M}\frac{(\Delta t)^2}{2}                             &amp;amp;=\delta r_A\frac{M_A}{M_A-M} &amp;amp; i\in \bar{A} \\&lt;br /&gt;
\end{cases}&lt;br /&gt;
\end{align} &amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
このとき &amp;lt;math&amp;gt;\lambda&amp;lt;/math&amp;gt; は拘束条件 &amp;lt;math&amp;gt;g&amp;lt;/math&amp;gt; を満たすように決まるため、&lt;br /&gt;
&amp;lt;math&amp;gt;\lambda&amp;lt;/math&amp;gt; を求めるために解くべき方程式は次式となる。&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;\begin{align}&lt;br /&gt;
g &amp;amp;= \frac{\sum_{i\in A}m_i(r_i^0+\delta r_i)}{M_A} - \frac{\sum_j m_j(r_j^0+\delta r_j)}{M} - \Delta R \\&lt;br /&gt;
  &amp;amp;= \frac{\sum_{i\in A}m_ir_i^0}{M_A}+\delta r_A^0 -R_0 - \Delta R = 0&lt;br /&gt;
\end{align} &amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
従って、グループ &amp;lt;math&amp;gt;A&amp;lt;/math&amp;gt; に属する粒子の拘束力による変位は&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;\begin{align}&lt;br /&gt;
\delta r_A &lt;br /&gt;
&amp;amp;= \Delta R - \frac{\sum_{i\in A}m_ir_i^0}{M_A} + R_0 \\&lt;br /&gt;
&amp;amp;= R_A - \frac{\sum_{i\in A}m_ir_i^0}{M_A}&lt;br /&gt;
\end{align}&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
となる。また、グループ &amp;lt;math&amp;gt;A&amp;lt;/math&amp;gt; に属さない粒子の変位はこれに &amp;lt;math&amp;gt;M_A/(M_A-M)&amp;lt;/math&amp;gt; をかけたものとなる。&lt;br /&gt;
ここまで議論した変位は ''MoveA'' における &amp;lt;math&amp;gt;t \rightarrow t + \Delta t&amp;lt;/math&amp;gt;の時間発展である。&lt;br /&gt;
これに対応する速度の変化は &amp;lt;math&amp;gt;t \rightarrow t + \Delta t/2&amp;lt;/math&amp;gt; の時間発展であるから、&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;\begin{align}&lt;br /&gt;
\delta v_i = \frac{\delta r_i}{\Delta t}&lt;br /&gt;
\end{align}&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
となる。&lt;br /&gt;
また、&amp;lt;math&amp;gt;g&amp;lt;/math&amp;gt; の時間微分も拘束条件として課される。&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;\begin{align}&lt;br /&gt;
\frac{dg}{dt} = \frac{\sum_{i\in A}m_iv_i}{M_A} - \frac{\sum_jm_jv_j}{M} = 0&lt;br /&gt;
\end{align}&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
拘束力による速度変化は、&amp;lt;math&amp;gt;t + \Delta t/2 \rightarrow t + \Delta t&amp;lt;/math&amp;gt; における時間発展であるから、&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;\begin{align}&lt;br /&gt;
\delta v_i &lt;br /&gt;
= \lambda\frac{\partial g}{\partial r_i}\frac{\Delta t}{2m_i}&lt;br /&gt;
= &lt;br /&gt;
\begin{cases}&lt;br /&gt;
\lambda\Bigl(\frac{1}{M_A} - \frac{1}{M}\Bigr)\frac{\Delta t}{2} &amp;amp;\equiv \delta v_A &amp;amp; i\in A \\&lt;br /&gt;
-\frac{\lambda}{M}\frac{\Delta t}{2} &amp;amp;= \delta v_A\Bigl(\frac{M_A}{M_A-M}\Bigr) &amp;amp; i\in \bar{A}&lt;br /&gt;
\end{cases}&lt;br /&gt;
\end{align}&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
となる。ただし重心の速度は0である。&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;\begin{align}&lt;br /&gt;
\frac{\sum_i m_iv_i^0}{M} = 0&lt;br /&gt;
\end{align}&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
従って拘束力を求めるために解くべき方程式は&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;\begin{align}&lt;br /&gt;
\frac{dg}{dt}&lt;br /&gt;
&amp;amp;= \frac{1}{M_A}\sum_{i\in A}m_i(v_i^0+\delta v_i) - \frac{1}{M}\sum_j m_j(v_j^0+\delta v_j) \\&lt;br /&gt;
&amp;amp;= \frac{\sum_{i\in A}m_iv_i^0}{M_A} + \delta v_A = 0&lt;br /&gt;
\end{align}&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
であり、速度変化はこれを解いて次式となる。&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;\begin{align}&lt;br /&gt;
\delta v_A = -\frac{\sum_{i\in A}m_iv_i^0}{M_A}&lt;br /&gt;
\end{align}&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== 平均力と拘束力 ==&lt;br /&gt;
結構ムズイのであきらめた。&lt;br /&gt;
&lt;br /&gt;
Giovanni Ciccotti, Raymond Kapral, and Eric Vanden-Eijnden, &amp;quot;Blue moon sampling, vectorial reaction coordinates, and unbiased constrained dynamics,&amp;quot; ChemPhysChem 6 (2005) 1809-1814.&lt;br /&gt;
&lt;br /&gt;
Michiel Sprik and Giovanni Ciccotti, &amp;quot;Free energy from constrained molecular dynamics,&amp;quot; J. Chem. Phys. 109 (1998) 7737-7744.&lt;br /&gt;
&lt;br /&gt;
　FreeFlex version 1.0以降では、通常のRATTLE法に加え、質量のないサイトに対する拘束や特異点のある拘束条件に対する拘束アルゴリズム（SF-RATTLE）をサポートするよう改良がなされた。&lt;br /&gt;
　また、これに伴い通常のRATTLE法に対しても若干の修正が加えられており、これらについて説明する。&lt;br /&gt;
&lt;br /&gt;
== SF-RATTLE ==&lt;br /&gt;
FreeFlexでは一般化座標を用いて、自由な拘束条件を課すことができる。&lt;br /&gt;
ただし拘束条件の種類によってはRATTLE拘束に対して特異点となる場合があり、これを回避するために特別なアルゴリズム（SF-RATTLE）を&lt;br /&gt;
用いる必要がある。&lt;br /&gt;
例えば粒子1, 2, 3のなす角 &amp;lt;math&amp;gt;\theta&amp;lt;/math&amp;gt; を &amp;lt;math&amp;gt;\theta_0&amp;lt;/math&amp;gt; に固定するような拘束条件&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;\begin{align}&lt;br /&gt;
g=\cos{\theta}-\cos{\theta_0}=0&lt;br /&gt;
\end{align}&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
に対して、&amp;lt;math&amp;gt;\cos{\theta}=0, \pi&amp;lt;/math&amp;gt; は g の微分が 0 になるために拘束力の向きが決まらず、特異点となっている。&lt;br /&gt;
&lt;br /&gt;
== 質量のないサイトを含む拘束条件 ==&lt;br /&gt;
TIP4P、TIP5PやCRK水モデルをはじめとして、ダミーサイトを含む分子モデルがしばしば用いられる。&lt;br /&gt;
通常のRATTLE法をこれらの拘束条件に直接適用することはできないが（拘束力 &amp;lt;math&amp;gt;F_i^\mathrm{con}&amp;lt;/math&amp;gt; による&lt;br /&gt;
変位 &amp;lt;math&amp;gt;\delta r_i = \frac{(\Delta t)^2}{2m_i}F_i^\mathrm{con}&amp;lt;/math&amp;gt; が &amp;lt;math&amp;gt;m_i\rightarrow 0&amp;lt;/math&amp;gt;で発散する）&lt;br /&gt;
、ダミーサイトに働く力を質量のあるサイトに分配することで通常のRATTLE法と同様に取り扱うことが可能となる。&lt;br /&gt;
&lt;br /&gt;
ダミーサイトの座標は、質量を持つ粒子との拘束条件によって決められる。&lt;br /&gt;
従って、ダミーサイトには通常3つの（独立な）拘束条件がかかるべきであり、これ以上の拘束は冗長である。&lt;br /&gt;
現行のFreeFlexでは4つ以上の拘束条件を許容しないので拘束条件は冗長に置かないように注意する。&lt;/div&gt;</summary>
		<author><name>Hirano</name></author>
	</entry>
</feed>