ラベル 粒子法 の投稿を表示しています。 すべての投稿を表示
ラベル 粒子法 の投稿を表示しています。 すべての投稿を表示

2009年9月27日日曜日

SPHによる巻き波のシミュレーション第2回

前回のエントリでは、可動壁によって波を起こすことで巻き波のシミュレーションをしようとしたが、うまく巻き波が起きなかった。

そこで、巻き波を起こすにはどうしたらいいのかいろいろと調べてみたところ、RadovitzkyとOritzの"Lagrangian finite element analytics of newtonian fluid flows."という論文を見つけた。

この論文は、有限要素法によってラグランジュ的に自由表面をシミュレーションする手法を提示している。その適用例の1つとして砕波を扱っており、そこに孤立波の理論解が示されていた。これを適用すれば波の岸に打ち寄せる波を再現することができそう。

孤立波の初期条件は、水面の高さをη、x方向の初速をu、y方向の初速をvとすると、



のようになる(x方向のオフセットを省略)。ここで、gは重力加速度で9.8[m/s^2]、Hとdはそれぞれ基準となる水面の高さと波の高さである。

また、tanhとsechは双曲線関数で、その定義は



である。

この初期条件を適用して、またシミュレーションしてみると、



お!巻き波が起きた!

シミュレーション結果を見ると、左から進んできた孤立波が、斜面にさしかかったところでせり上がって、巻き波になってくずれる様子が見てとれる。また、巻き波が打ち寄せたあとにさーっと引いていく様子も、実際の砂浜とよく似ている。

いい感じに巻き波が起きるようになったので、次は、このエントリのように綺麗にレンダリングしてみます。

■関連するエントリ
SPHによる巻き波のシミュレーション第1回
SPHによる巻き波のシミュレーション第3回
-

2009年9月16日水曜日

SPHによる巻き波のシミュレーション第1回


波の一種に巻き波というものがある。浅海域に進入した波が対称性を失って、前面が切り立った壁のようになり、頂部の水が前に飛び出す形で巻くように砕けるものをいう。

粒子法では、しぶきがあがるような激しい変形を表現することができる。そこで、巻き波をシミュレーションしたいと思った。



左側の境界条件を周期的に動かすことで波を起こしている。また、真ん中から右は斜面になっている。

ところが、結果をみてみるとうまくいかない…

波が減衰して斜面まで届かないのと、斜面の底部分で不自然に左向きの流れが起きているのが気になる。

波が減衰してしまう点については、容器の形や可動壁の動きを調整しようと思う。

斜面の底部分で不自然な流れが起きている点については、理由がよくわからない…境界条件にはペナルティ法を使っているが、そのせいで斜面方向に変に力がかかっているんだろうか?

もうすこし調整が必要そうだ。

■関連するエントリ
SPHによる巻き波のシミュレーション第2回
SPHによる巻き波のシミュレーション第3回
-

2009年8月29日土曜日

【論文】p = k ( ρ - ρ0 )でのρ0の意味


Mullerらの"Particle-Based Fluid Simulation for Interactive Applications"では、圧力pを密度ρから求める際に、定常密度ρ0を引いて
p = k(ρ - ρ0)
としている(kは定数)。ρ0を引く理由としてMullerらは、
... Since pressure forces depend on the gradient of the pressure field, the offset mathematically has not effect on pressure forces. However, the offset does influence the gradient of a field smoothed by SPH and makes the simulation numerically more stable. ...
と述べている。

なんのこっちゃ?

オフセット(ρ0)が数学的に圧力に影響を与えないといいつつ、それによってシミュレーションがより安定化するといっている。しかし、数学的に影響を与えないのであれば、安定化するもなにもないではないか。

そこで、引用元である、Desbrunの"Smoothed Particels: A new paradigm for animating highly deformable bodies"の中で、なぜρ0が導入されているのかを見てみた。

Desbrunらによると、
... In astrophysics applications, pressure forces were often combined with gravitational forces balancing the expansion phenomenon.
  In contrast, we would like to animate materials with constant density at rest. Consequently, the material sould exhibit some internal cohesion, resulting in attraction-repulsino forces as in the Lennard-Jones model. ...
とある。

なるほど。

もともとSPHは天体のシミュレーションで用いられていた手法なので、真空中での粒子の運動を対象としている。一方で、Desbrunらが行おうとしている大変形体のシミュレーションは、大気中での運動が対象となる。

大気中での運動なので、本来であれば、大変形体の周りに空気があって、その気圧と大変形体の圧力が釣り合っていないといけない。

それを論文でどう扱っているかというと、周りの空気も粒子としてシミュレーションに含めるのではなく、その代わりに、ρからρ0を引いて気圧の影響を補正した圧力を用いるという方法をとっている。つまり、定常状態での圧力を仮想的に0気圧となるようにオフセットをとって計算している。

つまり、定常状態での圧力を仮想的に0気圧とすることで、気圧と大変形体の圧力を釣り合わせているということになる。

実際に、ρ0を変えてシミュレーションをしてみた。

【ρ0=600】


【ρ0=300】


【ρ0=0】


確かに、ρ0が小さくなるにつれて、粒子が空気中に広がっていっている様子がわかる。ρ0=0に至っては、まさに真空中に拡散しているように見える結果が得られた。

結論
圧力pを密度ρから求める際に定常密度ρ0を引いてp = k (ρ - ρ0)とするのは、気圧の影響を加味して粒子が拡散してしまわないようにするためだった。SPHを宇宙から地球上に持ってくるわけですな。

■関連する記事
粒子法のプログラム第1回(概要)
粒子法のプログラム第2回(プログラムの大枠)
粒子法のプログラム第3回(データ構造)
粒子法のプログラム第4回(密度と圧力の計算)
粒子法のプログラム第5回(力の計算)
粒子法のプログラム第6回(境界条件と粒子位置の更新)
粒子法のプログラム最終回(粒子の出力)
【粒子法】粒子を流体としてレンダリング
3次元の粒子法シミュレーション
粒子法のシーンを2倍のサイズにしてみたが…

2009年8月24日月曜日

粒子法のシーンを2倍のサイズにしてみた


粒子法のシーンを2倍のサイズにしてみたが…」で失敗したものをもう一度計算した。

【2倍のサイズ】


【元のサイズ】


初期配置や境界の形はまったく同じにして、xyz各方向に2倍している。一見同じように見えるけど、床のチェック模様の細かさが違うところに注目して欲しい。

2倍サイズにすると、より高いところからさらに多くの流体が落下するため、盛大なしぶきがあがった。上のレンダリング結果だと黒くなってしまってわかりづらいが、陰関数曲面をそのままレンダリングするとその様子がよくわかる。





粒子法(SPH)のプログラム
粒子法(SPH)のプログラムを解説したシリーズです。ソースコードも公開しています。

粒子法(SPH)のプログラム一覧



動画
シミュレーションの結果をレンダリングして作った動画です。流体シミュレーションや剛体シミュレーションの動画を見ることができます。

動画の一覧



--

2009年8月23日日曜日

【論文】Particle-Based Fluid Simulation for Interactive Applications


Matthias Mullerらの「Particle-Based Fluid Simulation for Interactive Applications」を読んだ。

この論文では、SPHをベースに、自由表面を持つ流体をインタラクティブにシミュレーションしレンダリングする方法を提案している。

この論文におけるMullerらの貢献は、
  • Desbrunらの大変形体向けの手法を流体に拡張
  • インタラクティビティの実現
の2点。

Desbrunの手法を流体に拡張するにあたり、Mullerらは流体が受ける力をナビエ=ストークス方程式から直接導出するようにし、さらに、表面張力をモデル化した項を加えることを提案している。

また、インタラクティブに流体を描画できるように、高速に計算できるカーネルを設計すると共に、キャッシュヒット率が向上するようデータ構造を工夫している。

レンダリングにはPoint SplattingとMarching Cubesの2通りの手法を用いており、2003年当時のPC(Pentium4+GeForce4)で2000個程度の粒子を計算した例では、Point Splattingで20fps、Marching Cubesで5fpsでの描画を実現している。

粒子法のシーンを2倍のサイズにしてみたが…


3次元の粒子法シミュレーションを、さらにシーンを2倍のサイズにして計算してみた。



あ…カメラの位置を調節していなかった…
再計算します。

追記:再計算しました。こちら


■関連する記事
粒子法のプログラム第1回(概要)
粒子法のプログラム第2回(プログラムの大枠)
粒子法のプログラム第3回(データ構造)
粒子法のプログラム第4回(密度と圧力の計算)
粒子法のプログラム第5回(力の計算)
粒子法のプログラム第6回(境界条件と粒子位置の更新)
粒子法のプログラム最終回(粒子の出力)
【粒子法】粒子を流体としてレンダリング
3次元の粒子法シミュレーション
粒子法のシーンを2倍のサイズにしてみたが…
粒子法のシーンを2倍のサイズにしてみた

3次元の粒子法シミュレーション


粒子法のプログラム第1回(概要)【粒子法】粒子を流体としてレンダリングでは粒子を2次元で計算していたので、今回はそれを3次元に拡張して計算してみた。平面だったものを、そのままz方向にも粒子を配置している。


【粒子表現】


【流体表現】



■流体シミュレーションに関するエントリ
粒子法のプログラム第1回(概要)
粒子法のプログラム第2回(プログラムの大枠)
粒子法のプログラム第3回(データ構造)
粒子法のプログラム第4回(密度と圧力の計算)
粒子法のプログラム第5回(力の計算)
粒子法のプログラム第6回(境界条件と粒子位置の更新)
粒子法のプログラム最終回(粒子の出力)
【粒子法】粒子を流体としてレンダリング
3次元の粒子法シミュレーション
粒子法のシーンを2倍のサイズにしてみたが…
粒子法のシーンを2倍のサイズにしてみた
SPHによる巻き波のシミュレーション2
Haskell、OCamlでSPH法
このあとやりたいこと
カメラ位置を変えて流体をレンダリング
固液連成シミュレーション

■剛体シミュレーションに関するエントリ
粒子ベース剛体シミュレーション(プレビュー)
粒子ベース多体衝突シミュレーション
引き続き、粒子ベース剛体シミュレーション


粒子法(SPH)のプログラム
粒子法(SPH)のプログラムを解説したシリーズです。ソースコードも公開しています。

粒子法(SPH)のプログラム一覧



動画
シミュレーションの結果をレンダリングして作った動画です。流体シミュレーションや剛体シミュレーションの動画を見ることができます。

動画の一覧


--

2009年7月11日土曜日

粒子法のプログラム最終回(粒子の出力)


最終回となる今回は、計算した粒子の出力について説明します。

このプログラムでは、計算した粒子をpov-rayのフォーマットで出力しています。

第1回に載せたムービーは、このプログラムでタイムステップごとに出力した.povファイルをレンダリングし、さらにffmpegで動画にしたものです。

粒子を出力するコードは以下のようになっています。

void output_particles( Particles* ps )
{
static int num = 0;
std::string file_name = \
(boost::format( "result%08d.pov" ) % num++ ).str();
std::cout << "processing " << file_name << " ..." << std::endl;
std::ofstream f( file_name.c_str() );
if ( ! f )
{
std::cerr << "cannot open " << file_name << std::endl;
exit(1);
}

f << "#include ¥"colors.inc¥"¥n"
<< "camera {¥n"
<< "  location <10,>¥n"
<< "  look_at <10,>¥n"
<< "}¥n"
<< "light_source { <0,> color White }¥n";
FOR_EACH_PARTICLES( ps, p )
{
f << "sphere {¥n"
<< "  <" << r(0) << ", " << r(1) << ", " << r(2) << ">, 0.5¥n"
<< "  texture {¥n"
<< "    pigment { color Yellow }¥n"
<< "  }¥n"
<< "}¥n";
}
f << std::endl;
}
タイムステップごとに.povファイルを出力しています。

さらに、この投稿に載せたムービーでは、計算した粒子から求めた陰曲面をマーチングキューブでポリゴン化し、反射や屈折も考慮してレンダリングしています。

これでひととおりの説明が終わりました。このあとの発展としては、3次元にしたり、物体との相互作用を入れたり、GPUで処理したりといったことを考えています。

粒子法のプログラム
粒子法のプログラム第1回(概要)
粒子法のプログラム第2回(プログラムの大枠)
粒子法のプログラム第3回(データ構造)
粒子法のプログラム第4回(密度と圧力の計算)
粒子法のプログラム第5回(力の計算)
粒子法のプログラム第6回(境界条件と粒子位置の更新)
粒子法のプログラム最終回(粒子の出力)

その他の解説エントリ
SPHによる巻き波のシミュレーション1
SPHによる巻き波のシミュレーション2
SPHによる巻き波のシミュレーション3
このあとやりたいこと

固液連成シミュレーションに関するエントリ
粒子法による固液連成シミュレーション

流体シミュレーションに関するエントリ
【粒子法】粒子を流体としてレンダリング
3次元の粒子法シミュレーション
粒子法のシーンを2倍のサイズにしてみたが…
粒子法のシーンを2倍のサイズにしてみた
Haskell、OCamlでSPH法
カメラ位置を変えて流体をレンダリング
Bunny-shaped fluid simulation

剛体シミュレーションに関するエントリ
粒子ベース剛体シミュレーション(プレビュー)
粒子ベース多体衝突シミュレーション
引き続き、粒子ベース剛体シミュレーション
Falling Rigid Bunnies

動画
シミュレーションの結果をレンダリングして作った動画です。流体シミュレーションや剛体シミュレーションの動画を見ることができます。

動画の一覧


--

2009年6月20日土曜日

粒子法のプログラム第6回(境界条件と粒子位置の更新)


今回は、粒子の境界条件と粒子位置の更新について説明します。

境界条件と粒子位置の更新のコードは以下のようになります。

void calculate_position( Particles* ps )
{
vec accel(3), g(3), norm(3);
double speed, diff, adj;

g(0) = 0.0; g(1) = -9.8; g(2) = 0.0;
FOR_EACH_PARTICLES( ps, p )
{
accel = p->f * SPH_PMASS;

speed = norm2( accel );
if ( speed > SPH_LIMIT*SPH_LIMIT ) {
accel *= SPH_LIMIT / sqrt(speed);
}

// Z-axis walls
diff = 2.0 * RADIUS - ( p->r(2) - MIN(2) ) * SPH_SIMSCALE;
if ( diff > EPSILON )
{
norm(0) = 0.0; norm(1) = 0.0; norm(2) = 1.0;
adj = SPH_EXTSTIFF * diff - SPH_EXTDAMP * inner_prod( norm, p->v );
accel += adj * norm;
}
diff = 2.0 * RADIUS - ( MAX(2) - p->r(2) ) * SPH_SIMSCALE;
if ( diff > EPSILON )
{
norm(0) = 0.0; norm(1) = 0.0; norm(2) = -1.0;
adj = SPH_EXTSTIFF * diff - SPH_EXTDAMP * inner_prod( norm, p->v );
accel += adj * norm;
}

// X-axis walls
diff = 2.0 * RADIUS - ( p->r(0) - MIN(0) ) * SPH_SIMSCALE;
if ( diff > EPSILON )
{
norm(0) = 1.0; norm(1) = 0.0; norm(2) = 0.0;
adj = SPH_EXTSTIFF * diff - SPH_EXTDAMP * inner_prod( norm, p->v );
accel += adj * norm;
}
diff = 2.0 * RADIUS - ( MAX(0) - p->r(0) ) * SPH_SIMSCALE;
if ( diff > EPSILON )
{
norm(0) = -1.0; norm(1) = 0.0; norm(2) = 0.0;
adj = SPH_EXTSTIFF * diff - SPH_EXTDAMP * inner_prod( norm, p->v );
accel += adj * norm;
}

// Y-axis walls
diff = 2.0 * RADIUS - ( p->r(1) - MIN(1) ) * SPH_SIMSCALE;
if ( diff > EPSILON )
{
norm(0) = 0.0; norm(1) = 1.0; norm(2) = 0.0;
adj = SPH_EXTSTIFF * diff - SPH_EXTDAMP * inner_prod( norm, p->v );
accel += adj * norm;
}
diff = 2.0 * RADIUS - ( MAX(1) - p->r(1) ) * SPH_SIMSCALE;
if ( diff > EPSILON )
{
norm(0) = 0.0; norm(1) = -1.0; norm(2) = 0.0;
adj = SPH_EXTSTIFF * diff - SPH_EXTDAMP * inner_prod( norm, p->v );
accel += adj * norm;
}

accel += g;
p->v += accel * DT;
p->r += p->v * DT / SPH_SIMSCALE;

// stick on x-y plane
p->r(2) = 0.0;

}
}
それぞれの粒子について、粒子にかかる力から加速度を計算したあと、各壁面について境界条件を適用し、重力加速度を加えます。そうやって求まった加速度から、粒子の速度を求め、粒子の位置を更新します。

境界条件には、ペナルティ法を用いています。ペナルティ法とは、粒子が壁面へめりこんだ場合に、そのめり込みの程度によって壁面との衝突による反発力を与える方法です。

このようにして、境界条件を処理し、粒子の位置を更新しています。

次回は計算結果の出力です。最終回です。

粒子法のプログラム
粒子法のプログラム第1回(概要)
粒子法のプログラム第2回(プログラムの大枠)
粒子法のプログラム第3回(データ構造)
粒子法のプログラム第4回(密度と圧力の計算)
粒子法のプログラム第5回(力の計算)
粒子法のプログラム第6回(境界条件と粒子位置の更新)
粒子法のプログラム最終回(粒子の出力)

その他の解説エントリ
SPHによる巻き波のシミュレーション1
SPHによる巻き波のシミュレーション2
SPHによる巻き波のシミュレーション3
このあとやりたいこと

固液連成シミュレーションに関するエントリ
粒子法による固液連成シミュレーション

流体シミュレーションに関するエントリ
【粒子法】粒子を流体としてレンダリング
3次元の粒子法シミュレーション
粒子法のシーンを2倍のサイズにしてみたが…
粒子法のシーンを2倍のサイズにしてみた
Haskell、OCamlでSPH法
カメラ位置を変えて流体をレンダリング
Bunny-shaped fluid simulation

剛体シミュレーションに関するエントリ
粒子ベース剛体シミュレーション(プレビュー)
粒子ベース多体衝突シミュレーション
引き続き、粒子ベース剛体シミュレーション
Falling Rigid Bunnies

動画
シミュレーションの結果をレンダリングして作った動画です。流体シミュレーションや剛体シミュレーションの動画を見ることができます。

動画の一覧


--

2009年5月30日土曜日

粒子法のプログラム第5回(力の計算)


今回は、粒子法のプログラムでどのように力を計算しているかを説明します。

力の計算は次のコードになります。


void calculate_force( Particles* ps )
{
double pterm, vterm, r, c;
vec dr(3), force(3), fcurr(3);

FOR_EACH_PARTICLES( ps, p )
{
force(0) = 0.0; force(1) = 0.0; force(2) = 0.0;
FOR_EACH_PARTICLES( ps, pj )
{
if ( p == pj ) continue;
dr = ( p->r - pj->r ) * SPH_SIMSCALE;
r = norm( dr );
if ( H > r )
{
c = H - r;
pterm = -0.5 * c * SpikyKern * ( p->p + pj->p ) / r;
vterm = LapKern * SPH_VISC;
fcurr = pterm * dr + vterm * ( pj->v - p->v );
fcurr *= c * p->rho * pj->rho;
force += fcurr;
}
}
p->f = force;
}
}
それぞれの粒子について、ナビエ=ストークス方程式の圧力項、粘性項にあたる力を計算しています。

影響半径内にある自分以外の粒子に対して、距離に応じて重みを足し合わせています。SpikyKernとLapKernがカーネルの係数です。

力の計算も、密度と圧力の計算と同様に、近傍粒子探索を工夫したり対称性を利用することで、高速化できます。

次回は、どのように粒子の位置を更新するかという説明になります。

粒子法のプログラム
粒子法のプログラム第1回(概要)
粒子法のプログラム第2回(プログラムの大枠)
粒子法のプログラム第3回(データ構造)
粒子法のプログラム第4回(密度と圧力の計算)
粒子法のプログラム第5回(力の計算)
粒子法のプログラム第6回(境界条件と粒子位置の更新)
粒子法のプログラム最終回(粒子の出力)

その他の解説エントリ
SPHによる巻き波のシミュレーション1
SPHによる巻き波のシミュレーション2
SPHによる巻き波のシミュレーション3
このあとやりたいこと

固液連成シミュレーションに関するエントリ
粒子法による固液連成シミュレーション

流体シミュレーションに関するエントリ
【粒子法】粒子を流体としてレンダリング
3次元の粒子法シミュレーション
粒子法のシーンを2倍のサイズにしてみたが…
粒子法のシーンを2倍のサイズにしてみた
Haskell、OCamlでSPH法
カメラ位置を変えて流体をレンダリング
Bunny-shaped fluid simulation

剛体シミュレーションに関するエントリ
粒子ベース剛体シミュレーション(プレビュー)
粒子ベース多体衝突シミュレーション
引き続き、粒子ベース剛体シミュレーション
Falling Rigid Bunnies

動画
シミュレーションの結果をレンダリングして作った動画です。流体シミュレーションや剛体シミュレーションの動画を見ることができます。

動画の一覧


--

2009年5月23日土曜日

粒子法のプログラム第4回(密度と圧力の計算)


今回は、粒子法のプログラムでどのように密度と圧力を計算しているかを説明します。

粒子の密度と圧力の計算は次のコードになります。
void calculate_density_and_pressure( Particles* ps )
{
double r2, c, sum, H2;
vec dr;

H2 = H*H;

FOR_EACH_PARTICLES( ps, p )
{
sum = 0.0;
FOR_EACH_PARTICLES( ps, pj )
{
if ( p == pj ) continue;
dr = (p->r - pj->r) * SPH_SIMSCALE;
r2 = norm2( dr );
if ( H2 > r2 )
{
c = H2 - r2;
sum += c * c * c;
}
}
p->rho = sum * SPH_PMASS * Poly6Kern;
p->p   = ( p->rho - SPH_RESTDENSITY ) * SPH_INTSTIFF;
p->rho = 1.0 / p->rho;  // take inverse for later calculation
}
}

それぞれの粒子について、影響半径内にある自分以外の粒子に対して、距離に応じて重みを足し合わせています。そのあと、足し合わせた重みに、粒子質量についての係数とカーネル係数をかけています。密度が計算された後、圧力を密度から計算します。

上のやり方だと、計算量のオーダーは、各粒子について他の粒子それぞれとの計算になるので、粒子の数をnとするとO(n^2)となります。しかし、影響半径外の粒子との計算は不要なので、他粒子すべてと計算する必要は本来ありません。なので、近傍粒子をあらかじめマップに入れておき、それを参照するようにすれば、計算量をO(n)にすることができます。

また、粒子pと粒子pjについて対称なので、その対称性を利用すれば、計算量をさらに半分にすることが可能です。

密度と圧力は、このように計算されています。いったん素直な実装になっていますが、上の2つの点で高速化することができます。

次回は、粒子にかかる力をどのように計算しているかという説明です。

粒子法のプログラム
粒子法のプログラム第1回(概要)
粒子法のプログラム第2回(プログラムの大枠)
粒子法のプログラム第3回(データ構造)
粒子法のプログラム第4回(密度と圧力の計算)
粒子法のプログラム第5回(力の計算)
粒子法のプログラム第6回(境界条件と粒子位置の更新)
粒子法のプログラム最終回(粒子の出力)

その他の解説エントリ
SPHによる巻き波のシミュレーション1
SPHによる巻き波のシミュレーション2
SPHによる巻き波のシミュレーション3
このあとやりたいこと

固液連成シミュレーションに関するエントリ
粒子法による固液連成シミュレーション

流体シミュレーションに関するエントリ
【粒子法】粒子を流体としてレンダリング
3次元の粒子法シミュレーション
粒子法のシーンを2倍のサイズにしてみたが…
粒子法のシーンを2倍のサイズにしてみた
Haskell、OCamlでSPH法
カメラ位置を変えて流体をレンダリング
Bunny-shaped fluid simulation

剛体シミュレーションに関するエントリ
粒子ベース剛体シミュレーション(プレビュー)
粒子ベース多体衝突シミュレーション
引き続き、粒子ベース剛体シミュレーション
Falling Rigid Bunnies

動画
シミュレーションの結果をレンダリングして作った動画です。流体シミュレーションや剛体シミュレーションの動画を見ることができます。

動画の一覧


--

2009年5月19日火曜日

【粒子法】粒子を流体としてレンダリング


粒子法では流体を粒子として表現します。

そのため、そのまま描画すると、この投稿のように球のあつまりとして描画することになります。

これを、流体として見えるようにレンダリングしてみました。

マーチングキューブで陰曲面をポリゴン化し、レイトレーシングでレンダリングしています。

フォトンマップも使っているのでコースティクスも表現されています。

屈折率を高めにしたのでキラキラ。




■固液連成シミュレーションに関するエントリ
粒子法による固液連成シミュレーション

■関連する記事
粒子法のプログラム第1回(概要)
粒子法のプログラム第2回(プログラムの大枠)
粒子法のプログラム第3回(データ構造)
粒子法のプログラム第4回(密度と圧力の計算)
粒子法のプログラム第5回(力の計算)
粒子法のプログラム第6回(境界条件と粒子位置の更新)
粒子法のプログラム最終回(粒子の出力)
【粒子法】粒子を流体としてレンダリング
3次元の粒子法シミュレーション
粒子法のシーンを2倍のサイズにしてみたが…
粒子法のシーンを2倍のサイズにしてみた

粒子法(SPH)のプログラム
粒子法(SPH)のプログラムを解説したシリーズです。ソースコードも公開しています。

粒子法(SPH)のプログラム一覧



動画
シミュレーションの結果をレンダリングして作った動画です。流体シミュレーションや剛体シミュレーションの動画を見ることができます。

動画の一覧


--

2009年4月19日日曜日

粒子法のプログラム第3回(データ構造)


今回は、粒子法のプログラムのデータ構造を説明します。

使用したデータ構造は、Particle構造体とParticlesベクタの2つです。

Particles構造体は以下です。
typedef boost::numeric::ublas::vector<double> vec;
typedef struct
{
vec    r;
vec    v;
double rho;
double p;
vec    f;
} Particle;
boostライブラリのublasを使い、3次元ベクトルを表現しています。
rは粒子座標、vは粒子速度、rhoは粒子地点での密度、pは粒子地点での圧力、fは粒子が受ける力です。

Particlesベクタは以下です。
typedef std::vector<particle> Particles;
STLのvectorコンテナでParticle構造体のベクタを表現しています。

使用しているデータ構造は、この2つのみです。このように、粒子法はデータ構造が非常に簡単なのが特徴です。

次回からは、粒子法のアルゴリズムの説明になります。


粒子法のプログラム
粒子法のプログラム第1回(概要)
粒子法のプログラム第2回(プログラムの大枠)
粒子法のプログラム第3回(データ構造)
粒子法のプログラム第4回(密度と圧力の計算)
粒子法のプログラム第5回(力の計算)
粒子法のプログラム第6回(境界条件と粒子位置の更新)
粒子法のプログラム最終回(粒子の出力)

その他の解説エントリ
SPHによる巻き波のシミュレーション1
SPHによる巻き波のシミュレーション2
SPHによる巻き波のシミュレーション3
このあとやりたいこと

固液連成シミュレーションに関するエントリ
粒子法による固液連成シミュレーション

流体シミュレーションに関するエントリ
【粒子法】粒子を流体としてレンダリング
3次元の粒子法シミュレーション
粒子法のシーンを2倍のサイズにしてみたが…
粒子法のシーンを2倍のサイズにしてみた
Haskell、OCamlでSPH法
カメラ位置を変えて流体をレンダリング
Bunny-shaped fluid simulation

剛体シミュレーションに関するエントリ
粒子ベース剛体シミュレーション(プレビュー)
粒子ベース多体衝突シミュレーション
引き続き、粒子ベース剛体シミュレーション
Falling Rigid Bunnies

動画
シミュレーションの結果をレンダリングして作った動画です。流体シミュレーションや剛体シミュレーションの動画を見ることができます。

動画の一覧


--

2009年2月28日土曜日

粒子法のプログラム第2回(プログラムの大枠)


プログラムの大枠が上の図です。

まず初期化をします。

そのあと密度と圧力を計算し、力を計算し、粒子の位置を更新します。

粒子の位置を更新したら、そのステップでの結果をファイルに出力し、また密度と圧力の計算へ戻ります。

これを、指定ステップ数だけ繰り返します。


粒子法のプログラム
粒子法のプログラム第1回(概要)
粒子法のプログラム第2回(プログラムの大枠)
粒子法のプログラム第3回(データ構造)
粒子法のプログラム第4回(密度と圧力の計算)
粒子法のプログラム第5回(力の計算)
粒子法のプログラム第6回(境界条件と粒子位置の更新)
粒子法のプログラム最終回(粒子の出力)

その他の解説エントリ
SPHによる巻き波のシミュレーション1
SPHによる巻き波のシミュレーション2
SPHによる巻き波のシミュレーション3
このあとやりたいこと

固液連成シミュレーションに関するエントリ
粒子法による固液連成シミュレーション

流体シミュレーションに関するエントリ
【粒子法】粒子を流体としてレンダリング
3次元の粒子法シミュレーション
粒子法のシーンを2倍のサイズにしてみたが…
粒子法のシーンを2倍のサイズにしてみた
Haskell、OCamlでSPH法
カメラ位置を変えて流体をレンダリング
Bunny-shaped fluid simulation

剛体シミュレーションに関するエントリ
粒子ベース剛体シミュレーション(プレビュー)
粒子ベース多体衝突シミュレーション
引き続き、粒子ベース剛体シミュレーション
Falling Rigid Bunnies

動画
シミュレーションの結果をレンダリングして作った動画です。流体シミュレーションや剛体シミュレーションの動画を見ることができます。

動画の一覧


--

2009年2月23日月曜日

粒子法のプログラム第1回(概要)


粒子法のプログラムを実装しようとしたのですが、論文や本だと数式レベルでしか説明がなく、それをプログラムにして動くようにするまで苦労しました。

数式をプログラムに落とすこと自体は簡単なのですが、各定数の値が分からなかったりして、粒子が上手く動いてくれるまで大変でした。

なので、同じところでつまづく人も多いのではと思い、自分が書いた粒子法のプログラムを紹介しようと思います。下の動画を作ったときのプログラムです。SPH法です。



こちらがソースコードです。

※2009.11.4追記 こちらに整理したC++版のほか、Haskell版、OCaml版のコードがあります。

まずはシンプルにと考え、近傍粒子の探索は工夫せず、n(O^2)ですがわかりやすいアルゴリズムを採用しています。まず動くコードを書き、そこから高速化していくアプローチです。

また、計算量を減らした方が試しやすいのと、粒子法は3次元への拡張が簡単なことから、まずは2次元で実装しています。

プログラムの中身を別の記事で少しずつ説明していこうと思います。

粒子法のプログラム
粒子法のプログラム第1回(概要)
粒子法のプログラム第2回(プログラムの大枠)
粒子法のプログラム第3回(データ構造)
粒子法のプログラム第4回(密度と圧力の計算)
粒子法のプログラム第5回(力の計算)
粒子法のプログラム第6回(境界条件と粒子位置の更新)
粒子法のプログラム最終回(粒子の出力)

その他の解説エントリ
SPHによる巻き波のシミュレーション1
SPHによる巻き波のシミュレーション2
SPHによる巻き波のシミュレーション3
このあとやりたいこと

固液連成シミュレーションに関するエントリ
粒子法による固液連成シミュレーション

流体シミュレーションに関するエントリ
【粒子法】粒子を流体としてレンダリング
3次元の粒子法シミュレーション
粒子法のシーンを2倍のサイズにしてみたが…
粒子法のシーンを2倍のサイズにしてみた
Haskell、OCamlでSPH法
カメラ位置を変えて流体をレンダリング
Bunny-shaped fluid simulation

剛体シミュレーションに関するエントリ
粒子ベース剛体シミュレーション(プレビュー)
粒子ベース多体衝突シミュレーション
引き続き、粒子ベース剛体シミュレーション
Falling Rigid Bunnies

動画
シミュレーションの結果をレンダリングして作った動画です。流体シミュレーションや剛体シミュレーションの動画を見ることができます。

動画の一覧


--

2008年3月31日月曜日

粒子法シミュレーション—物理ベースCG入門

東大の越塚さんによる、粒子法の入門書。

つい今月出版されたみたい。

Amazonで注文したが、まったく内容を見ずに買ったので少し不安。

粒子法というのは、流体をコンピュータでシミュレーションする方法の一つ。

流体をコンピュータでシミュレーションする方法には、大きく分けて2つある。

メッシュベースのアプローチとパーティクルベースのアプローチ。

粒子法というのは、その名の通りパーティクルベースのアプローチ。

パーティクルベースのアプローチの特徴は、波や雫といった液体表面の状態を表現しやすいという点。

この記事にソースコードを置いています。

■関連する記事
粒子法のプログラム第1回(概要)
粒子法のプログラム第2回(プログラムの大枠)
粒子法のプログラム第3回(データ構造)
粒子法のプログラム第4回(密度と圧力の計算)
粒子法のプログラム第5回(力の計算)
粒子法のプログラム第6回(境界条件と粒子位置の更新)
粒子法のプログラム最終回(粒子の出力)
【粒子法】粒子を流体としてレンダリング
3次元の粒子法シミュレーション
粒子法のシーンを2倍のサイズにしてみたが…
粒子法のシーンを2倍のサイズにしてみた