MDACP 取り扱い説明書

設計思想

MDの実行エンジンクラス MDUnitを通してすべての作業を行う。 複数のプロジェクトになるべく一つのコードで対応する。 そのため、ProjectManagerクラスがパラメータファイルのModeに応じた 適切なProjectクラス(の子クラス)にMDUnitのインスタンスを渡す。 ユーザはProjectクラスのRunメソッドの中を記述することでMDを実行する仕組みとなっている。

コンパイルの仕方

 コンパイルにはMPIが必要。MPIライブラリの無い環境ではコンパイルができないため、先にインストールしておくこと。

 最初にmakefile.optを作成し、コンパイラ(CC)およびコンパイルオプション(CPPFLAGS)、 必要ならばライブラリオプション(LDFLAGS)を記述しておく。その上で、

$ make
とすれば動くはず。 素早くコンパイルしたい場合は、make -jが良い。 以下はmakefile.optの記述例。 IBM Power系の石の場合は「-DPOWER」をつけたほうが速くなる。 Opteronなど、Intel系でもつけたほうが早い場合がある。

動作確認

 コンパイルができたら、実行してみる。デフォルトではベンチマークを取る。 以下のように表示されたら成功。

$ ./mdacp
# Number of Processes: 1
# Input file is not specified. input.cfg is used.
# Mode = Benchmark
# Number of Particles = 62500
# System Size = (50,50,50)
# Desity = 0.5
# Cutoff Length  = 2.5
# TimeStep = 0.001
# ControlTemperature = no
# IsPeriodic = yes
#Energy = -2.00818
0.151 0.364681 -2.00818# observe
0.251 0.36874 -2.00819# observe
0.351 0.444665 -2.00816# observe
0.451 0.496116 -2.00817# observe
0.551 0.518531 -2.00817# observe
0.651 0.541055 -2.00817# observe
0.751 0.559876 -2.00817# observe
0.851 0.577013 -2.00817# observe
0.951 0.588248 -2.00818# observe
1.051 0.599503 -2.00818# observe
#Energy = -2.00817
# N=62500 21.6639 [SEC] 2.88498 [MUPS]
# Number of Pair-list Construction: 17

 次に、並列実行をしてみる。例えば8並列なら

$ mpirun -np 8 ./mdacp
とする。以下のような表示がされるはず。
$ mpirun -np 8 ./mdacp
# Number of Processes: 8
# Input file is not specified. input.cfg is used.
# Mode = Benchmark
# Number of Particles = 500000
# System Size = (100,100,100)
# Desity = 0.5
# Cutoff Length  = 2.5
# TimeStep = 0.001
# ControlTemperature = no
# IsPeriodic = yes
#Energy = -2.00818
0.151 0.365109 -2.00818# observe
0.251 0.369157 -2.00819# observe
0.351 0.445891 -2.00816# observe
0.451 0.496593 -2.00817# observe
0.551 0.521196 -2.00817# observe
0.651 0.542904 -2.00817# observe
0.751 0.561414 -2.00817# observe
0.851 0.576258 -2.00817# observe
0.951 0.588979 -2.00817# observe
1.051 0.599142 -2.00817# observe
#Energy = -2.00817
# N=500000 43.1095 [SEC] 11.5984 [MUPS]
# Number of Pair-list Construction: 18

パラメータの渡し方

 パラメータファイル(*.cfg)を用意し、それを第一引数に渡す。

$ mpirun -np 8 ./mdacp hoge.cfg
インプットファイルを省略した場合には、input.cfgが読み込まれる。

パラメータファイルは

parameter1=value1
parameter2=value2
parameter3=value3
の形で羅列する。文頭に#をつければコメントとして解釈される。 以下、大事なパラメータ(予約語)。

予約語以外は自分で好きなように設定してよい。 設定するものとしては、InitialVelocityやTotalLoop、ControlTemperatureなど。 全てはParameterクラスのインスタンス、paramに入って渡されてくるので、 Parameter::GetIntegerなどで値を受け取る。

モードについて

 一つのコードで複数のプロジェクトに対応するため、モードを指定することで動作を分けている。 具体的にはProjectManager::ExecuteProject内でModeを判別し、もしMode=Benchmarkならbenchmark.cc内のBenchmark::Runを、 Mode=Collisionならcollision.cc内のCollision::Runを呼ぶようにしている。 たとえばCollision::Runの引数としてMDUnitのインスタンスmduと Parameterのインスタンスparamが 渡されるので、ユーザはそれを通じてシミュレーションを行う。

 Projectクラスを継承したクラスを作成することで新しいプロジェクトを作ることができる。 たとえば液滴衝突モード「Collision」は、collision.cc/collision.hに実装がある。 まず、collision.hにProjectクラスの派生クラスとして Collisionクラスが定義され、コンストラクタで

ProjectManager::GetInstance().AddProject("Collision",this);
と、プロジェクトの追加のためのコードが呼ばれている。 これはcollision.ccにある
Collision collision;
によりインスタンスが静的に作られる時に呼ばれ、自動的にProjectManagerは 「Collision」モードを知り、対応するProjectクラスのインスタンスを得る。 その後、main関数にて読み込まれたパラメタファイルのModeが「Collision」であれば、Collisionクラスの インスタンスのRunメソッドを呼ぶ。

シミュレーションの進め方

パラメータの受け取り

 パラメータファイルに書いた情報はparamのメソッドを呼ぶことで受け取る。 もし

Density=0.70
と書いた情報を受け取りたければ、
double density = param.GetDoubleDef("Density",0.5)
などとする。この例では、もし「Density」がパラメタファイルに記述されていなければ0.5が設定される。 同様に、整数や真偽値も受け取ることができる。 たとえばループ数TotalLoopは
TotalLoop=1000
とパラメータファイルに記述しておき、
const int TOTAL_LOOP =param.GetIntegerDef("TotalLoop",1000);
と受け取る。
IsPeriodic=yes
ControlTemperature=no
などは、
bool isPeriodic = param.GetBooleanDef("IsPeriodic",false);
bool controlTemperature = param.GetBooleanDef("ControlTemperature",false);
などとして受け取る。

粒子の配置

 粒子の配置にはMDUnit::AddParticleを使う。 AddParticle(double x[D], double v[D])は、xを位置、vを速度とするような 粒子を追加する。どのプロセスに追加するべきかは自動的に判定される。 もし 座標(50,50,50)に速度0の粒子を追加したければ、

double x[D],v[D];
x[X] =50.0;
y[Y] =50.0;
z[Z] =50.0;
v[X] = 0;
v[Y] = 0;
v[Z] = 0;
mdu->AddParticle(x,v);
とすれば良い。

時間発展

 時間を一ステップ進めるには、Calculateメソッドを呼ぶ。 現在の時間はGetSimulationTime、温度はTemperature、全エネルギーはTotalEnergyで分かる。 もしTOTAL_LOOPだけループをまわす間、 OBSERVE_LOOPステップごとに時間と温度を表示したければ、

  for (int i=0; i<TOTAL_LOOP; i++) {
    mdu->Calculate();
    if (i%OBSERVE_LOOP==0) {
      mout << mdu->GetSimulationTime() << " "<< mdu->Temperature() << endl;
    }
  }
などとすればよい。

その他使いそうなMDUnitのメソッド

ソースとクラスの説明

主なクラス

その他のクラス