(57)【特許請求の範囲】
【請求項１】
分子中の原子の位置を基に分子軌道法を用いて分子中の原子に作用する力ベクトルを求めるシミュレーションと、当該力ベクトルを基に分子動力学法を用いて分子の動的な性質を求めるシミュレーションとを統合するためのインターフェースを生成するシミュレーション開発支援装置であって、
ユーザにより定義されたインターフェース定義ファイルを基に、前記複数のシミュレーション間でのデータの授受を司る前記インターフェースを生成する自動生成手段を備え、
前記自動生成手段は、前記原子の位置および力ベクトルをデータとして含む前記原子のクラスと前記分子のクラスとを階層関係を持たせて生成し、前記分子のクラスにおける、前記原子のクラスのデータへのアクセスの仕方をクロージャとして生成することを特徴とするシミュレーション開発支援装置。
【請求項２】
前記自動生成手段は、前記原子のクラスと前記分子のクラスとの間の中間階層のクラスを生成し、前記中間階層のクラスにおける、前記原子のクラスのデータへのアクセスの仕方をクロージャとして生成する請求項１に記載のシミュレーション開発支援装置。
【請求項３】
コンピュータにより実行され、分子中の原子の位置を基に分子軌道法を用いて分子中の原子に作用する力ベクトルを求めるシミュレーションと、当該力ベクトルを基に分子動力学法を用いて分子の動的な性質を求めるシミュレーションとを統合するためのインターフェースを生成するシミュレーション開発支援方法であって、
ユーザにより定義されたインターフェース定義ファイルを基に、前記複数のシミュレーション間でのデータの授受を司る前記インターフェースを生成する自動生成工程を備え、
前記自動生成工程は、前記原子の位置および力ベクトルをデータとして含む前記原子のクラスと前記分子のクラスとを階層関係を持たせて生成し、前記分子のクラスにおける、前記原子のクラスのデータへのアクセスの仕方をクロージャとして生成することを特徴とするシミュレーション開発支援方法。
【請求項４】
コンピュータにより実行され、分子中の原子の位置を基に分子軌道法を用いて分子中の原子に作用する力ベクトルを求めるシミュレーションと、当該力ベクトルを基に分子動力学法を用いて分子の動的な性質を求めるシミュレーションとを統合するためのインターフェースを生成するシミュレーション開発支援プログラムであって、
ユーザにより定義されたインターフェース定義ファイルを基に、前記複数のシミュレーション間でのデータの授受を司る前記インターフェースを生成する自動生成手段、として前記コンピュータを機能させ、
前記自動生成手段は、前記原子の位置および力ベクトルをデータとして含む前記原子のクラスと前記分子のクラスとを階層関係を持たせて生成し、前記分子のクラスにおける、前記原子のクラスのデータへのアクセスの仕方をクロージャとして生成することを特徴とするシミュレーション開発支援プログラム。
【発明の詳細な説明】
【技術分野】
【０００１】
本発明は、複数のシミュレーションを統合してシミュレーションを行う際のインターフェースを生成する技術に関する。
【背景技術】
【０００２】
近年、シミュレーション手法の高度化により、単一のシミュレーションだけでは望みの結果が得られず、複数のシミュレーションを組み合わせることが多くなってきている。このような統合化されたシミュレーションには、全体的な枠組みを与えるシミュレーションと、その枠組みから繰り返し呼び出される要素的なシミュレーションとが含まれている。
【０００３】
このような統合化されたシミュレーションの一例としては、全体的な枠組みを与えるシミュレーションのアルゴリズムとして分子動力学法が用いられ、要素的なシミュレーションのアルゴリズムとして分子軌道法が用いられた分子シミュレーションが挙げられる。要素的なシミュレーションのアルゴリズムとしては、分子軌道法の他に、Tight-Binding Modelによる電子状態計算、密度汎関数法、経験的ポテンシャル（AMBER、CHARMM）、あるいはＱＭ／ＭＭ（quantum mechanics/molecular mechanics）法などを用いることもできる。また、全体的な枠組みを与えるシミュレーションのアルゴリズムとしては、分子動力学法の他に、モンテカルロ法、徐冷法、構造最適化、自由エネルギー変化の計算、非平衡グリーン関数法、あるいはＥＳＱＣ（Elastic Scattering Quantum Chemistry technique）法などを用いることもできる。
【０００４】
このようにシミュレーションのアルゴリズムの種類は増える一方であるが、全体的な枠組みを与えるシミュレーションプログラムの中に要素的なシミュレーションプログラムを統合するのは難しい。現状では、全体的な枠組みを与えるシミュレーションプログラム及び要素的なシミュレーションプログラムのそれぞれのソースコードを解析して修正することで、統合化されたシミュレーションプログラムが開発されている。しかし、この方法によれば、開発に時間がかかる。そのため、統合化されたシミュレーションプログラムを効率的に開発するための種々の方法が提案されている（オブジェクト指向型技術を用いた開発例として非特許文献１、適切なシミュレーションパラメータを見つける手法の例として特許文献１）。
【先行技術文献】
【非特許文献】
【０００５】
【非特許文献１】"MDScope - a visual computing environment for structural biology", K. Schulten et al. Computer Physics Communications Volume 91, Issues 1-3, 2 September 1995, Pages 111-133
【特許文献】
【０００６】
【特許文献１】特開２００８−１５８７８１号公報
【発明の概要】
【発明が解決しようとする課題】
【０００７】
しかしながら、上述の種々の方法によっても、統合化されたシミュレーションプログラムの開発の煩雑さを軽減することは難しい。この煩雑さの原因としては、２つの原因が考えられる。１つ目の原因は、統合されるべき複数のシミュレーションプログラムの間で授受されるデータは一定の内部構造を保っている必要があるからである。つまり、当該複数のシミュレーションプログラムの間でデータの内部構造や入出力フォーマットは共通ではないため、入力出ファイルを接続しただけでは、統合化されたシミュレーションプログラムは動作せず、込み入ったコードを追加することが要求されるのである。２つ目の原因は、複数のシミュレーションプログラム間におけるデータの授受は正確に行われることが要求されるため、この正確さを実現するために手作業で多くの段階を踏んでエラーをチェックする必要があるからである。つまり、データの授受は正確に自動化されている必要があるが、この正確さを実現するための時間がかかるとともに、手作業でエラーをチェックすることによるヒューマンエラーが入ってしまう可能性がある。
【０００８】
つまり、ユーザは、統合化されたシミュレーションプログラムを開発する際には、複数のシミュレーション間で授受されるデータへのアクセス方法を意識することが要求されるため、開発が煩雑となる。
【課題を解決するための手段】
【０００９】
開示の装置は、複数のシミュレーションを統合した統合化シミュレーションを開発するためのインターフェースを生成するシミュレーション開発支援装置であって、ユーザにより定義されたインターフェース定義ファイルを基に、前記複数のシミュレーション間でのデータの授受を司る前記インターフェースを生成する自動生成手段を備え、前記自動生成手段は、前記複数のシミュレーション間で授受されるデータを保持するクラスを生成するとともに、当該データへのアクセスの仕方をクロージャとして生成する。
【００１０】
開示の装置は、例えばＰＣ（Personal Computer）などのコンピュータであり、自動生成手段を備える。自動生成手段は、コンピュータにおいてプログラムが実行されることにより実現され、ユーザにより定義されたインターフェース定義ファイルを基に、複数のシミュレーション間でのデータの授受を司るインターフェースを生成する。ここで、自動生成手段は、複数のシミュレーション間で授受されるデータを保持するクラスを生成するとともに、当該データへのアクセスの仕方をクロージャとして生成する。
【発明の効果】
【００１１】
開示の装置によれば、ユーザは、自動生成されたインターフェースを用いることにより、複数のシミュレーション間で授受されるデータへのアクセス方法を意識することなく、統合化されたシミュレーションプログラムを開発することができる。
【図面の簡単な説明】
【００１２】
【図１】実施形態に係るシミュレーション装置の構成の一例を示す模式図である。
【図２】分子シミュレーションプログラムの統合例を示す模式図である。
【図３】比較例に係る統合化プログラムの開発方法の一例を示す模式図である。
【図４】ユーザが定義するクラスと自動生成されるクラスとの関係の一例を示すクラス図である。
【図５】各クラスのインスタンスの間の相互作用の一例を示すシーケンス図である。
【図６】各クラスのインスタンスの間の相互作用の一例を示すシーケンス図である。
【図７】分子と原子との間に中間階層が想定された場合に自動生成されるクラスの一例を示すクラス図である。
【図８】原子クラスの自動生成処理を示すフローチャートの一例である。
【図９】中間階層クラスの自動生成処理を示すフローチャートの一例である。
【図１０】中間階層クラスの自動生成処理を示すフローチャートの一例である。
【図１１】分子クラスの自動生成処理を示すフローチャートの一例である。
【発明を実施するための形態】
【００１３】
以下、実施形態の一例について図面を参照しつつ説明する。
【００１４】
［装置構成］
まず、実施形態に係るシミュレーション装置の構成の一例について図１を用いて説明する。図１は、実施形態に係るシミュレーション装置１００の構成の一例を示すブロック図である。
【００１５】
シミュレーション装置１００は、例えばＰＣ（Personal Computer）などのコンピュータであり、制御部１１と、メモリ１２と、入力部１３と、ハードディスク１４と、出力部１５とを有する。これらの構成要素は、バス１０を介して互いに接続されている。制御部１１は、例えばＣＰＵ（Central Processing Unit）であり、メモリ１２は、例えばＲＡＭ（Random Access Memory）であり、入力部１３は、例えばマウスやキーボードであり、出力部１５は、例えばディスプレイである。制御部１１は、入力部１３を介して入力されたユーザからの指示に応じて、ハードディスク１４に記憶されたプログラムを一時的にメモリ１２に記憶させてから当該プログラムを実行する。
【００１６】
［分子シミュレーション］
次に、上述のシミュレーション装置１００における分子シミュレーション方法について説明する。上述のシミュレーション装置１００では、制御部１１がプログラムを実行することにより分子シミュレーションが実行される。以下、図２を用いて具体的に説明する。
【００１７】
図２は、分子シミュレーションプログラムの一例を示す模式図である。実施形態に係る分子シミュレーションプログラムでは、分子動力学法および分子軌道法を用いて分子の動的な性質を調べる。図２に示す例では、分子動力学法のプログラムが統合化されたシミュレーションプログラム（以下、単に「統合化プログラム」と称する）に含まれており、統合化プログラムによって分子軌道法のプログラムが呼び出される。
【００１８】
図２において、「ｒ」とは分子構造、具体的には、分子に含まれる原子の位置ベクトルを示している。ここで、位置ベクトルは、例えば位置座標で示される。「Ｆ」とは当該原子に作用する力ベクトルを示している。また、「ｔ」は時間を示し、「Δｔ」はタイムステップを示している。ｒ（ｔ）は、位置ベクトルが時間の関数であることを示し、ｒ（０）は、位置ベクトルの初期値を示している。
【００１９】
図２に示す分子シミュレーションでは、分子中の各原子に作用する力ベクトルを求め、当該力ベクトルによる各原子の位置や速度の変化を調べる。具体的には、シミュレーション装置１００は、分子軌道法プログラムを実行することで、分子中の各原子の位置ベクトルを基に、分子中の各原子に作用する力ベクトルを求める。分子軌道法プログラムが実行されると、分子中の各原子に作用する力ベクトルがシュレディンガー方程式Ｅｑを用いて求められる。図２に示すシュレディンガー方程式Ｅｑにおいて、「Ｈ」はハミルトニアンを示し、「Ｅ」は電子エネルギーを示し、「Ψ」は波動関数を示している。
【００２０】
そして、シミュレーション装置１００は、分子軌道法プログラムより求められた力ベクトルを基に、分子動力学法プログラムを実行することにより、分子中の各原子の位置や速度の変化を求める。図２において、「Ｍ」は原子の質量、即ち、原子量を示している。具体的には、分子動力学法プログラムが実行されると、分子中の各原子の位置や速度の変化が運動方程式より求められる。そして、再度、シミュレーション装置１００は、分子軌道法プログラムを用いて、各原子の変化後の位置を基に、各原子に作用する力ベクトルを求めた後、分子動力学法プログラムを用いて、当該力ベクトルによる分子中の各原子の位置や速度の変化を求める。シミュレーション装置１００は、このような動作を繰り返し行うことで、分子の動的な性質をシミュレートする。
【００２１】
［統合化プログラムの開発を難しくしている点と、本発明による解決］
次に、統合化プログラムの開発方法について説明する。図３は、比較例に係る統合化プログラムの開発方法の一例を示す模式図である。
【００２２】
比較例に係る統合化プログラムの開発方法では、まず、ユーザは、分子軌道法プログラムとの間で物理量のデータを授受させるためのプログラムを開発する（ＰＳ１）。次に、ユーザは、物理量のデータを適切なデータ構造に設定するためのプログラムを開発する。ユーザは、例えば、分子軌道法プログラムに入力されるデータを、分子軌道法プログラムで要求される入力形式に適合させるプログラムを開発する（ＰＳ２Ａ）。また、ユーザは、分子軌道法プログラムより出力されたデータを分子動力学法のプログラムで要求される入力形式に適合させるプログラムを開発する（ＰＳ２Ｂ）。そして、ユーザは、統合化プログラムの残りの部分、例えば、分子動力学法のプログラムを開発する（ＰＳ３）。ユーザは、このようにして開発された各プログラムを統合した統合化プログラムを動作させ、正確に動作しなければ、上述のＰＳ１〜ＰＳ３の各開発工程を繰り返す。
【００２３】
しかしながら、上述のＰＳ１〜ＰＳ３の各開発工程を繰り返すことにより統合化プログラムを開発する場合には、時間がかかるだけでなく、手作業でプログラミングを行うことによるヒューマンエラーが入りやすい。また、比較例に係る統合化プログラムの開発方法では、分子軌道法のプログラムを別のプログラムに変えると、その影響は、統合化プログラムにおけるデータの入出力部からデータ構造の変換部（場合によっては、残りの統合化プログラムの部分）にまで及ぶ。そのため、この場合には、ユーザは、統合化プログラムのかなりの部分を書き直すことになる。
【００２４】
そこで、実施形態に係るシミュレーション装置１００は、ユーザにより定義されたインターフェース定義ファイルを基に、分子軌道法プログラムとのデータの授受を司るプログラミングインターフェースを自動生成することとする。つまり、実施形態に係るシミュレーション装置１００は、シミュレーション開発支援装置としても機能する。ユーザは、自動生成されたプログラミングインターフェースを用いて統合化プログラムを開発する。以下、具体的に説明する。
【００２５】
［ユーザが定義するクラスと自動生成されるクラスの関係］
図４は、ユーザが定義するクラスと自動生成されるクラスとの関係の一例を示すクラス図である。
【００２６】
インターフェース定義ファイルは、ユーザにより作成されるファイルであり、SimulationParserクラスを含んでいる。また、インターフェース定義ファイルには、分子−原子間の階層構造が定義される。図４に示す例では、分子と原子との間に残基などの中間的な階層が定義されておらず、分子の直下の階層に原子が存在する例を示している。AtomクラスおよびMoleculeクラスは、ユーザにより作成されたインターフェース定義ファイルを基に、シミュレーション装置１００により自動生成されるクラスである。以下では、Atomクラスのインスタンスを「Atomオブジェクト」と称することとし、Moleculeクラスのインスタンスを「Moleculeオブジェクト」と称することとする。
【００２７】
SimulationParserクラスは、ユーザにより定義されるクラスであり、分子軌道法と分子動力学法との間でのデータ授受方法を指定するためのクラスである。SimulationParserクラスでは、posGetters、forceSetters、atomMassesの各データがインスタンス変数として定義されるとともに、_init_（）、setInput（）、doCalc（）、parseOutput（）の各メソッドが定義される。
【００２８】
SimulationParserクラスにおいて、posGettersは、原子の位置座標を読み出すためのクロージャの配列であり、forceSettersは、力ベクトルを原子に設定するためのクロージャの配列であり、atomMassesは、原子の質量の配列である。_init_（）は、コンストラクタである。setInput（）は、分子軌道法プログラムの入力ファイルを作成し、当該入力ファイルに入力データとなる原子のデータ（質量、座標など）を書き込むメソッドである。具体的には、setInput（）メソッドは、posGettersおよびatomMassesの各データより、原子のデータを取得して入力ファイルに書き込む処理を行うメソッドである。doCalc（）は、分子軌道法プログラムをオペレーティングシステムの別プロセスとして呼び出し、setInput（）で作成した入力ファイルを分子軌道法プログラムへ渡して実行するメソッドである。parseOutput（）は、分子軌道法プログラムの出力ファイルを解析して力ベクトルを読み出し、Atomオブジェクトに力ベクトルを設定するメソッドである。具体的には、parseOutput（）メソッドは、分子軌道法プログラムの出力ファイルより読み出した各原子に作用する力ベクトルをforceSettersを用いてAtomオブジェクトに設定するメソッドである。
【００２９】
先に述べたように、AtomクラスおよびMoleculeクラスは、ユーザにより作成されたインターフェース定義ファイルを基に、シミュレーション開発支援装置１００により自動生成されるクラスである。Atomクラスは、原子にかかわるデータ構造をカプセル化するためのクラスであり、Moleculeクラスは、分子−原子の階層構造をカプセル化するためのクラスである。
【００３０】
Atomクラスでは、m、x,y,z、vx,vy,vz、fx,fy,fzの各データがインスタンス変数として定義されるとともに、_init_（）、getProperty（）、getPosition（）、getVelocity（）、setForce（）、leapFrog（）の各メソッドが定義される。
【００３１】
Atomクラスにおいて、mは原子の質量を示し、x,y,zは原子の位置座標を示し、vx,vy,vzは原子の速度を示し、fx,fy,fzは原子に作用する力ベクトルを示している。_init_（）は、コンストラクタである。getProperty（）は、原子の質量および位置座標を読み出すメソッドであり、getPosition（）は、原子の位置座標を読み出すメソッドであり、getVelocity（）は、原子の速度を読み出すメソッドである。また、setForce（）は、原子に作用する力ベクトルを読み出すメソッドである。leapFrog（）は、分子動力学法のプログラムを実行するメソッドである。
【００３２】
Moleculeクラスでは、atomsがインスタンス変数として定義されるとともに、_init_（）、getAtomPropertyClosures（）、getAtomPositionClosures（）、getAtomVelocityClosures（）、setAtomForceClosures（）、leapFrog（）の各メソッドが定義される。
【００３３】
Moleculeクラスにおいて、atomsは分子に含まれる全ての原子のAtomオブジェクトの配列を示している。_init_（）は、コンストラクタである。getAtomPropertyClosures（）は、分子に含まれる全ての原子のAtomオブジェクトのgetProperty（）メソッドへの参照の配列を返すメソッドである。getAtomPositionClosures（）は、分子に含まれる全ての原子のAtomオブジェクトのgetPosition（）メソッドへの参照の配列を返すメソッドである。getAtomVelocityClosures（）は、分子に含まれる全ての原子のAtomオブジェクトのgetVelocity（）メソッドへの参照の配列を返すメソッドである。setAtomForceClosures（）は、分子に含まれる全ての原子のAtomオブジェクトのsetForce（）メソッドへの参照の配列を返すメソッドである。leapFrog（）は、分子に含まれる全ての原子のAtomオブジェクトのleapFrog（）メソッドを呼び出すメソッドである。
【００３４】
［ユーザによるメインルーチンの作成手順］
ユーザは、自身が定義したSimulationParserクラス、自動生成されたAtomクラスおよびMoleculeクラスを用いて、分子軌道法と分子動力学法とが結合されたメインルーチンを作成する。具体的には、以下のような処理をおこなうコードを書く。
まず、メインルーチンにて、Atomクラスのコンストラクタを呼び出して、Atomオブジェクトを生成し、原子量、原子座標と速度の初期値を設定する。これらのAtomオブジェクトを配列に格納して、この配列を引数としてMoleculeクラスのコンストラクタを呼び出して、Moleculeオブジェクトを生成する。このMoleculeオブジェクトのインスタンスメソッド getAtomPropertyClosures()、setAtomPositionClousres()、setAtomVelocityClosures()、setAtomForceClosures()を呼び出して、返されたクロージャの配列をそれぞれ、変数 propGetters、positionGetters、volocityGetters、forceSettersに代入する。SimulationParserオブジェクトを生成するために、これらの変数を引数としてSimulationParserクラスのコンストラクタを呼び出す。また、メインルーチンには、分子シミュレーションの開始時刻starttimeおよび終了時刻endtimeが設定されるとともに時間ステップtimestepが設定される。シミュレーションのなかで、時間は連続的に変化するわけではなく、ここで、設定された時間ステップの刻み幅で、開始時刻starttimeから終了時刻endtimeまで離散的に変化する。
【００３５】
そして、ユーザは、メインルーチンにて、SimulationParserオブジェクトのsetInput（）、doCalc()、parseOutput（）の各インスタンスメソッドを順に呼び出し、および、MoleculeオブジェクトのleapFrog（）インスタンスメソッドを順に呼び出す。setInput（）メソッドにより、分子軌道法プログラムの入力ファイルが作成され、当該入力ファイルに入力データとなる原子のデータ（質量、座標など）が書き込まれる。doCalc（）メソッドにより、分子軌道法プログラムが呼び出され、当該入力ファイルが渡される。parseOutput（）メソッドにより、分子軌道法プログラムの出力ファイルより読み出した各原子に作用する力ベクトルがforceSettersに設定される。leapFrog（）メソッドにより、分子動力学法プログラムが実行され、分子中の各原子の位置および速度の変化が求められる。ここで、SimulationParerクラスのsetInput（）、doCalc()、parseOutput（）の各メソッド、および、MoleculeクラスのleapFrog（）メソッドは、シミュレーションの中の時刻が、開始時刻starttimeから終了時刻enttimeまで、時間ステップtimestepの刻みで離散的に増えていく間に、繰り返し呼び出されるように設定される。
【００３６】
また、上記の時刻に関するループの中で、クロージャの配列である positionGetter、velocityGettersから、その要素であるクロージャをひとつづつ取り出して、そのクロージャを実行することで各原子の位置座標と速度を読み出し、これらのデータファイルに書き込む。ちなみに、このようなメインルーチンをプログラミング言語Pythonで書くと、そのコードは以下のようなものになる。
---------------------<コード例はじめ>------------------------------------
atoms = [] 
#  原子オブジェクトの原子座標、速度などを初期化して、
#  原子オブジェクトを atomsリストに追加する処理。
mol = Molecule(atoms)
propGetters = mol.getAtomPropertyClosures()
positionGetters = mol.setAtomPositionClosures()
velocityGetters = mol.setAtomVelocityClosures()
forceSetters = mol.setAtomForceClosures()
parser = SimulationParser( propGetters, positionGetters, 
forceSetters )
timeStep = 0.1 # タイムステップ（時刻の変化幅）を設定。
for t in arange(startTime, endTime, timeStep):
parser.setInput()
parser.doCalc()
parser.parseOutput()
mol.leapFrog( timeStep )
for p, v in positionGetters, velocityGetters :
x, y, z = p()
vx, vy, vz = v()
# x, y, z, vx, vy, vz をデータファイルに書き込む処理。
---------------------<コード例おわり>------------------------------------
［メインルーチンにおけるオブジェクト間の相互作用］
次に、メインルーチンが実行されることによるSimulationParserクラス、Atomクラス、Molculeクラスの各クラスのインスタンス間の相互作用の一例について図５、図６に示すシーケンス図を用いて説明する。図５、図６において、「parser」は、SimulationParserクラスのインスタンス（SimulationParserオブジェクト）を示し、「mol」は、Moleculeオブジェクトを示し、「atoms[0]」「atoms[1]」は、分子中の２つの原子に対応するAtomオブジェクトを示す。
【００３７】
図５、６に示す例では、上述したように、メインルーチンは、SimulationParerオブジェクトのsetInput（）、doCalc()、parseOutput（）の各インスタンスメソッド、および、MoleculeオブジェクトのleapFrog（）インスタンスメソッドを順に呼び出す。以下、具体的に説明する。
【００３８】
まず、プログラム中のステップｔ１において、メインルーチンは、parserオブジェクトのsetInput（）メソッドを呼び出す。setInput（）メソッドは、インスタンス変数posGettersおよびatomMassesの各データより、原子のデータを取得して分子軌道法の入力ファイルに書き込むメソッドである。ここで、先に述べたように、posGettersには、MoleculeオブジェクトのgetAtomPositionClosures（）メソッドにより返された値が格納されている。従って、parserオブジェクトは、setInput（）メソッドがメインルーチンにより呼び出されると、分子に含まれる各原子のAtomオブジェクトのgetPosition（）メソッドを用いて、各原子の位置座標を取得することができる。図５に示す例では、parserオブジェクトは、atoms[0]およびatoms[1]の各Atomオブジェクトにおける位置座標のデータx,y,zを取得する。また、ステップｔ２において、parserオブジェクトは、分子中の残りの原子のAtomオブジェクトについても、getPosition（）メソッドを用いて位置座標のデータx,y,zを取得する。そして、parserオブジェクトは、setInput（）メソッドの中で定義された方法で、取得した位置座標のデータx,y,zを分子軌道法の入力ファイルに書き込む。このようにすることで、分子中の各原子の位置座標が書き込まれた分子軌道法の入力ファイルが作成される。なお、位置座標のデータx,y,zは、各原子で互いに異なるのは言うまでもない。
【００３９】
ステップｔ３において、メインルーチンは、parserオブジェクトのdoCalc（）メソッドを呼び出す。doCalc（）は、分子軌道法プログラムをオペレーティングシステムの別プロセスとして呼び出し、setInput（）で作成した入力ファイルを分子軌道法プログラムへ渡して実行するメソッドである。従って、parserオブジェクトは、doCalc（）メソッドがメインルーチンにより呼び出されると、doCalc（）メソッドの中で定義された方法で、分子軌道法プログラムを呼び出し、setInput（）メソッドで作成された入力ファイルを渡して実行する。これにより、分子中の各原子に作用する力ベクトルが求められる。
【００４０】
ステップｔ４において、メインルーチンは、parserオブジェクトのparseOutput（）メソッドを呼び出す。parseOutput（）は、分子軌道法プログラムの出力ファイルを解析して力ベクトルを読み出して、Atomオブジェクトに力ベクトルを設定するメソッドである。従って、parserオブジェクトは、parseOutput（）メソッドがメインルーチンにより呼び出されると、分子軌道法プログラムの出力ファイルを解析して分子中の各原子に作用する力ベクトルfx,fy,fzをそれぞれ読み出して配列forceSettersに格納されているクロージャに渡す。ここで、先に述べたように、forceSettersには、MoleculeオブジェクトのsetAtomForceClosures（）メソッドにより返された値が格納されている。従って、parserオブジェクトは、分子に含まれる各原子のAtomオブジェクトのsetForce（）メソッドを用いて、力ベクトルfx,fy,fzを各原子のAtomオブジェクトに設定することになる。図５に示す例では、parserオブジェクトは、atoms[0]およびatoms[1]の各Atomオブジェクトのそれぞれに、setForce（）メソッドを用いて、力ベクトルfx,fy,fzを設定する。また、ステップｔ５において、parserオブジェクトは、分子中の残りの原子のAtomオブジェクトについても、setForce（）メソッドを用いて、力ベクトルfx,fy,fzを設定する。なお、各原子に作用する力ベクトルfx,fy,fzは、各原子で互いに異なるのは言うまでもない。これにより、分子中の各原子に力ベクトルが作用するように設定される。
【００４１】
ステップｔ６において、メインルーチンは、MoleculeオブジェクトのleapFrog（）メソッドを呼び出す。MoleculeオブジェクトのleapFrog（）メソッドは、分子に含まれる全ての原子のAtomオブジェクトのleapFrog（）メソッドを呼び出すメソッドである。AtomオブジェクトのleapFrog（）メソッドは、分子動力学法のプログラムを実行するメソッドである。AtomオブジェクトのleapFrog（）メソッドは、設定された力ベクトルfx,fy,fzを基に、分子動力学法のアルゴリズムを用いて、時間ステップtimestepの分だけ、原子の位置および速度を変化させる。図６に示す例では、moleculeオブジェクトは、atoms[0]およびatoms[1]の各AtomオブジェクトのleapFrog（）メソッドを呼び出して、時間ステップtimestepの分だけ、原子の位置および速度を変化させる。また、ステップｔ７において、moleculeオブジェクトは、分子中の残りの原子のAtomオブジェクトについても、leapFrog（）メソッドを呼び出して、時間ステップtimestepの分だけ、原子の位置および速度を変化させる。
【００４２】
ステップｔ８において、メインルーチンは、moleculeオブジェクトのleapFrog（）メソッドの呼び出しを終えると、分子中の各AtomオブジェクトのgetPosition（）メソッドおよびgetVelocity（）メソッドを呼び出して、各原子の位置座標と速度とを読み取り、データファイルに出力する。ステップｔ９以降、メインルーチンは、残りの時間ステップについて、上述したのと同様の動作を繰り返す。
【００４３】
図５、６にて破線矢印で示した、getPosition（）メソッドによる処理とその返り値x,y,zを授受する処理、力ベクトルfx,fy,fzを授受する処理、setForce（）メソッドによる処理、leapFrog（）メソッドによる処理は、自動生成されるクラスの内部で行われる処理である。これらの、AtomオブジェクトのgetProperty（）、getPosition（）、getVelocity（）、setForce（）の各メソッドへの参照は、moleculeオブジェクトのgetAtomPropertyClosures（）、getAtomPositionClosures（）、getAtomVelocityClosures（）、setAtomForceClosures（）の各メソッドの返り値として得られ、クロージャの配列に格納される。従って、ユーザは、これらの処理をコードとして書かずに済み、計算の度に変化する原子の状態（位置、速度）を保持しつつ、保持された原子の状態を用いた計算が自動的になされることになる。つまり、クロージャを用いることで、分子中の全ての原子について漏れなく内部データを読み出したり、設定したりする処理を自動的に行うことができる。これにより、ユーザがAtomオブジェクトの内部データにアクセスする方法を意識することなくメインルーチンを開発することができる。
【００４４】
[分子と原子の間に中間的な階層を想定する場合]
なお、図４から図６に示した例では、分子と原子との間に残基などの中間的な階層を想定していなかったが、例えば、タンパク質分子の場合のように、アミノ酸残基、Ｎ末端、Ｃ末端といった中間的な階層を想定した分子シミュレーションを行う方が好適な場合がある。このような中間的な階層が想定された分子の分子シミュレーションを行う場合にも、上述したのと同様のプログラミングインターフェースを自動生成するとしても良い。
【００４５】
図７は、分子と原子との間に残基などの中間的な階層を想定された場合における自動生成されるクラスの一例を示すクラス図である。シミュレーション開発支援装置１００は、インターフェース定義ファイルに中間的な階層が記述されている場合には、中間的な階層のクラス（以下、「中間階層クラス」と称することもある）を自動生成する。
【００４６】
図７に示す例では、先に述べたAtomクラスとMoleculeクラスに加え、中間階層クラスであるResidueクラス、CTerminalクラス、NTerminalクラスが自動生成される。Residueクラスはアミノ酸残基を示すラッパークラスであり、CTerminalクラスはＣ末端を示すラッパークラスであり、NTerminalクラスはＮ末端を示すラッパークラスである。
【００４７】
Risidueクラスでは、Moleculeクラスと同様に、_init_（）_、getAtomPropertyClosures（）、getAtomPositionClosures（）、getAtomVelocityClosures（）、setAtomForceClosures（）、leapFrog（）の各メソッドが定義されている。また、Residueクラスでは、compornentsがインスタンス変数として定義されている。compornentsは、直上の階層のオブジェクトへの参照の配列（図７に示す例では、Atomオブジェクトへの参照の配列）を示している。また、同様に、CTerminalクラス、NTerminalクラスも、インスタンス変数 compoenentsと、Moleculeクラスと同じ種類のインスタンスメソッドを持つ。
【００４８】
このような中間的階層がある場合も、ユーザは、自身が定義したSimulationParserクラス、自動生成されたAtomクラス、Moleculeクラス、Residueクラス、CTerminalクラス、NTerminalクラスを用いて、分子軌道法と分子動力学法とが結合されたメインルーチンを作成する。これによっても、ユーザがAtomオブジェクトの内部データにアクセスする方法を意識することなくメインルーチンを開発することができる。
【００４９】
[クラスの自動生成処理]
次に、クラスの自動生成処理について図８〜図１１を用いて説明する。クラスの自動生成処理は、シミュレーション装置１００において、制御部１１がプログラムを実行することにより行われる。
【００５０】
まず、Atomクラスの自動生成処理について図８を用いて説明する。図８は、Atomクラスの自動生成処理を示すフローチャートである。
【００５１】
ステップＳ１０１において、制御部１１は、Atomクラスのクラス名を宣言する。ステップＳ１０２において、制御部１１は、Atomクラスのデータとして、原子の質量および位置座標、速度、力ベクトルに対応するインスタンス変数（図４、図７の例でいうと、「m」、「x,y,z」、「vx,vy,vz」、「fx,fy,fz」）を宣言する。（ただし、Pythonのように変数を動的に割り付ける言語では、ステップS102は省略される。）ステップＳ１０３において、制御部１１は、原子の質量と位置座標を引数とするコンストラクタを宣言する。そして、制御部１１は、コンストラクタ内の処理として、原子の質量と位置座標とをそれぞれ、対応するインスタンス変数に代入する処理を書き出すとともに、原子の速度と力ベクトルとに対応するインスタンス変数を初期化する（例えば「ゼロ」にする）処理を書き出す。
【００５２】
ステップＳ１０４において、制御部１１は、getProperty（）メソッドを宣言する。制御部１１は、getProperty（）メソッド内の処理として、原子の質量と位置座標とのそれぞれに対応するインスタンス変数の値を返す処理を書き出す。ステップＳ１０５において、制御部１１は、getPosition（）メソッドを宣言する。制御部１１は、getPosition（）メソッド内の処理として、原子の位置座標に対応するインスタンス変数の値を返す処理を書き出す。
【００５３】
ステップＳ１０６において、制御部１１は、getVelocity（）メソッドを宣言する。制御部１１は、getVelocity（）メソッド内の処理として、原子の速度に対応するインスタンス変数の値を返す処理を書き出す。ステップＳ１０７において、制御部１１は、setForce（）メソッドを宣言する。そして、制御部１１は、setForce（）メソッド内の処理として、setForce（）メソッドの引数を力ベクトルに対応するインスタンス変数に設定する処理を書き出す。ステップＳ１０８において、制御部１１は、時間ステップtimestepを引数とするleapFrog（）メソッドを宣言する。そして、制御部１１は、リープフロッグ法（あるいは他の運動方程式の積分方法）に従って、力ベクトルの強さに応じて、原子の位置座標および速度を時間ステップtimestepの分だけ変化させる処理を書き出す。この後、制御部１１は、Atomクラスの自動生成処理を終了する。このようにして、図４、図７に示したようなAtomクラスが自動生成される。
【００５４】
次に、制御部１１は、ユーザが書いたインターフェース定義ファイルに中間的な階層が定義されているか否かを判定する。制御部１１は、インターフェース定義ファイルに中間的な階層が定義されていると判定した場合には、中間階層クラスの自動生成処理を行う。一方、制御部１１は、インターフェース定義ファイルに中間的な階層が定義されていないと判定した場合には、Moleculeクラスの自動生成処理を行う。
【００５５】
まず、中間階層クラスの自動生成処理について図９、図１０を用いて説明する。図９、図１０は、中間階層クラスの自動生成処理を示すフローチャートである。
【００５６】
ステップＳ２０１において、制御部１１は、インターフェース定義ファイルに記載された中間的な階層の名前を中間階層クラスのクラス名として宣言する。ステップＳ２０２において、制御部１１は、直上の階層のオブジェクト（例えばAtomオブジェクト）の配列への参照をインスタンス変数（図７の例でいうと「compornets」）として宣言する。ステップＳ２０３において、制御部１１は、直上の階層のオブジェクトの配列への参照を引数とするコンストラクタを宣言する。そして、制御部１１は、コンストラクタ内の処理として、引数として受け取った配列への参照を当該インスタンス変数に代入する処理を書き出す。
【００５７】
ステップＳ２０４において、制御部１１は、getAtomPropertyClosures（）メソッドを宣言する。ステップＳ２０５において、制御部１１は、直上の階層のオブジェクトがAtomオブジェクトか否かを判定する。
【００５８】
制御部１１は、直上の階層のオブジェクトがAtomオブジェクトであると判定した場合には（ステップＳ２０５：Ｙｅｓ）、ステップＳ２０６の処理へ進む。ステップＳ２０６において、制御部１１は、インスタンス変数に配列として代入されている全てのAtomオブジェクトについて、そのgetProperty（）メソッドへの参照を取り出す。そして、制御部１１は、それらの参照全てを配列に入れて、ステップＳ２０４で宣言したgetAtomPropertyClosures（）メソッドの返り値とする処理を書き出す。一方、ステップＳ２０５において、制御部１１は、直上の階層のオブジェクトがAtomオブジェクトでないと判定した場合には（ステップＳ２０５：Ｎｏ）、ステップＳ２０７の処理へ進む。ステップＳ２０７において、制御部１１は、インスタンス変数に配列として代入されている全てのオブジェクトのgetAtomPropertyClosures（）メソッドを呼び出すことで、その返り値であるgetProperty（）メソッドへの参照を取り出す。そして、制御部１１は、それらの参照全てを配列に入れて、ステップＳ２０４で宣言したgetAtomPropertyClosures（）メソッドの返り値とする処理を書き出す。
【００５９】
ステップＳ２０８において、制御部１１は、getAtomPositionClosures（）メソッドを宣言する。ステップＳ２０９において、制御部１１は、直上の階層のオブジェクトがAtomオブジェクトか否かを判定する。
【００６０】
制御部１１は、直上の階層のオブジェクトがAtomオブジェクトであると判定した場合には（ステップＳ２０９：Ｙｅｓ）、ステップＳ２１０の処理へ進む。ステップＳ２１０において、制御部１１は、インスタンス変数に配列として代入されている全てのAtomオブジェクトについて、そのgetPosition（）メソッドへの参照を取り出す。そして、制御部１１は、それらの参照全てを配列に入れて、ステップＳ２０８で宣言したgetAtomPositionClosures（）メソッドの返り値とする処理を書き出す。一方、ステップＳ２０９において、制御部１１は、直上の階層のオブジェクトがAtomオブジェクトでないと判定した場合には（ステップＳ２０９：Ｎｏ）、ステップＳ２１１の処理へ進む。ステップＳ２１１において、制御部１１は、インスタンス変数に配列として代入されている全てのオブジェクトのgetAtomPositionClosures（）メソッドを呼び出すことで、その返り値であるgetPosition（）メソッドへの参照を取り出す。そして、制御部１１は、それらの参照全てを配列に入れて、ステップＳ２０８で宣言したgetAtomPositionClosures（）メソッドの返り値とする処理を書き出す。
【００６１】
ステップＳ２１２において、制御部１１は、getAtomVelocityClosures（）メソッドを宣言する。ステップＳ２１３において、制御部１１は、直上の階層のオブジェクトがAtomオブジェクトか否かを判定する。
【００６２】
制御部１１は、直上の階層のオブジェクトがAtomオブジェクトであると判定した場合には（ステップＳ２１３：Ｙｅｓ）、ステップＳ２１４の処理へ進む。ステップＳ２１４において、制御部１１は、インスタンス変数に配列として代入されている全てのAtomオブジェクトについて、そのgetVelocity（）メソッドへの参照を取り出す。そして、制御部１１は、それらの参照全てを配列に入れて、ステップＳ２１２で宣言したgetAtomVelocityClosures（）メソッドの返り値とする処理を書き出す。一方、ステップＳ２１３において、制御部１１は、直上の階層のオブジェクトがAtomオブジェクトでないと判定した場合には（ステップＳ２１３：Ｎｏ）、ステップＳ２１５の処理へ進む。ステップＳ２１５において、制御部１１は、インスタンス変数に配列として代入されている全てのオブジェクトのgetAtomVelocityClosures（）メソッドを呼び出すことで、その返り値であるgetVelocity（）メソッドへの参照を取り出す。そして、制御部１１は、それらの参照全てを配列に入れて、ステップＳ２１２で宣言したgetAtomVelocityClosures（）メソッドの返り値とする処理を書き出す。
【００６３】
ステップＳ２１６において、制御部１１は、setAtomForceClosures（）メソッドを宣言する。ステップＳ２１７において、制御部１１は、直上の階層のオブジェクトがAtomオブジェクトか否かを判定する。
【００６４】
制御部１１は、直上の階層のオブジェクトがAtomオブジェクトであると判定した場合には（ステップＳ２１７：Ｙｅｓ）、ステップＳ２１８の処理へ進む。ステップＳ２１８において、制御部１１は、インスタンス変数に配列として代入されている全てのAtomオブジェクトについて、そのsetForce（）メソッドへの参照を取り出す。そして、制御部１１は、それらの参照全てを配列に入れて、ステップＳ２１６で宣言したsetAtomForceClosures（）メソッドの返り値とする処理を書き出す。一方、ステップＳ２１７において、制御部１１は、直上の階層のオブジェクトがAtomオブジェクトでないと判定した場合には（ステップＳ２１７：Ｎｏ）、ステップＳ２１９の処理へ進む。ステップＳ２１９において、制御部１１は、インスタンス変数に配列として代入されている全てのオブジェクトのsetAtomForceClosures（）メソッドを呼び出すことで、その返り値であるsetForce（）メソッドへの参照を取り出す。そして、制御部１１は、それらの参照全てを配列に入れて、ステップＳ２１６で宣言したsetAtomForceClosures（）メソッドの返り値とする処理を書き出す。
【００６５】
ステップＳ２２０において、制御部１１は、leapFrog（）メソッドを宣言する。ステップＳ２２１において、制御部１１は、インスタンス変数に配列として代入されている全てのオブジェクトのleapFrog（）メソッドを呼び出す処理を書き出す。この後、制御部１１は、中間階層クラスの自動生成処理を終了する。このようにして、図７に示したような中間階層クラスが自動生成される。
【００６６】
次に、Moleculeクラスの自動生成処理について図１１を用いて説明する。図１１は、Moleculeクラスの自動生成処理を示すフローチャートである。
【００６７】
ステップＳ３０１において、制御部１１は、Moleculeクラスのクラス名を宣言する。ステップＳ３０２において、制御部１１は、直上の階層のオブジェクト（例えばAtomオブジェクト）の配列への参照をインスタンス変数として宣言する。ステップＳ３０３において、制御部１１は、直上の階層のオブジェクトの配列への参照を引数とするコンストラクタを宣言する。そして、制御部１１は、コンストラクタ内の処理として、引数として受け取った配列への参照を当該インスタンス変数に代入する処理を書き出す。
【００６８】
ステップＳ３０４において、制御部１１は、getAtomPropertyClosures（）、getAtomPositionClosures（）、getAtomVelocityClosures（）、setAtomForceClosures（）、leapFrog（）の各メソッドを宣言する。そして、制御部１１は、図９、図１０の中間階層クラスの自動生成処理におけるステップＳ２０４〜Ｓ２２１で述べたのと同様の処理を行うことで、当該各メソッドの処理を書き出す。この後、制御部１１は、Moleculeクラスの自動生成処理を終了する。このようにして、図４、図７に示したようなMoleculeクラスが自動生成される。
【００６９】
以上に述べたように、実施形態に係るシミュレーション装置１００では、階層関係にあるAtomクラスとMoleculeクラスとを自動生成し、Moleculeクラスにおける、Atomクラスのデータへのアクセスの仕方をクロージャとして生成している。このようにすることで、分子中の全ての原子について漏れなく内部データを読み出したり、設定したりする処理を自動的に行うことができる。つまり、実施形態に係るシミュレーション装置１００では、複数のシミュレーション間で授受されるデータを保持するクラスを生成するとともに、当該データへのアクセスの仕方をクロージャとして生成している。これにより、ユーザは、当該データにアクセスする方法を意識することなく統合化プログラムを開発することができる。
【００７０】
なお、実施形態は、上述した実施形態の例に限られるものではなく、特許請求の範囲及び明細書全体から読み取れる発明の要旨あるいは思想に反しない範囲で適宜変更可能である。
【符号の説明】
【００７１】
１０  バス
１１  制御部
１２  メモリ
１３  入力部
１４  ハードディスク
１５  出力部
１００  シミュレーション装置（シミュレーション開発支援装置）
【図１】
0005581829.tif 000002
【図２】
0005581829.tif 000003
【図３】
0005581829.tif 000004
【図４】
0005581829.tif 000005
【図５】
0005581829.tif 000006
【図６】
0005581829.tif 000007
【図７】
0005581829.tif 000008
【図８】
0005581829.tif 000009
【図９】
0005581829.tif 000010
【図１０】
0005581829.tif 000011
【図１１】
0005581829.tif 000012