Chainerで流流体計算
PFI・PFNセミナー  2015/8/20
Preferred  Networks  Inc.
松元  叡⼀一
Github
l  この発表に関するコードはこちら
–  https://github.com/mattya/chainer-‐‑‒fluid
⾃自⼰己紹介
l  松元  叡⼀一  (@mattya1089)
l  東⼤大理理物→総合⽂文化研究科修⼠士卒
l  今年年4⽉月からPFN
l  DQN(去年年のPFIインターン)
l  分散深層強化学習
https://www.youtube.com/watch?
v=a3AWpeOjkzw
http://www.ustream.tv/recorded/53153399
Chainerで流流体計算
l  Chainer使って変なこと(Deep  Learning以外で)したい
l  Cupyの登場でGPU側のデータの扱いが楽になった
–  スライスとったり値を直接代⼊入したり
l  Autograd  (Chainer黎黎明期に少し話題になったライブラリ)
–  https://github.com/HIPS/autograd/
l  よし、流流体計算だ
l  ※数式がごりごり出てきますが    
    気楽に聞いてください
こんなのが作れる!
(発表準備時間のほとんどを
このパラメタチューニングに費やしてしまった。。。)
流流体⽅方程式
l  こんなのを解きたい(https://ja.wikipedia.org/wiki/渦度度・流流れ関数法)
移流流拡散⽅方程式(時間依存偏微分⽅方程式)
ポアソン⽅方程式
微分⽅方程式を解く
l  オイラー法
x = x_init
for i in xrange(T/dt):
dxdt = f(x)
x = x + dt * dxdt
時刻Tでのxが求まる
dx
dt
= v
dv
dt
= −
k
m
x −
c
m
v
d
!
x
dt
= f (
!
x)
例例:バネ
l  a
無駄にGPU
偏微分⽅方程式
l  空間に分布してるp(x)
偏微分⽅方程式
l  空間に分布してるp(x)
l  コンピュータでは離離散化して表現
p[0] p[1] p[2] p[3] p[4] p[5]…
間隔dx
偏微分⽅方程式
l  空間に分布してるp(x)
l  コンピュータでは離離散化して表現
p[0] p[1] p[2] p[3] p[4] p[5]…
間隔dx
dp
dx
を(p[i+1]-p[i-1])/(2*dx)  で近似
(中⼼心差分法)
dpdx[2] = (p[3]-p[1])/dx
この計算をすべてのiについて⾏行行う
[-1, 0, 1]のカーネルでConvolution
偏微分⽅方程式
l  空間に分布してるp(x)
l  コンピュータでは離離散化して表現
p[0] p[1] p[2] p[3] p[4] p[5]…
間隔dx
dp
dx
を (p[ i+1 ]-p[ i-1 ])/(2*dx)  
で近似(中⼼心差分法)
d2
p
dx2
を (p[ i+1 ]+p[ i-1 ]-2*p[ i ])/(dx*dx)  
で近似 ( (p[i+1]-p[i])/dx – (p[i]-p[i-1])/dx) / dx
[1, -2, 1]でのConvolution
偏微分⽅方程式
l  ⼆二次元に分布してても同様
u[0,0] u[0,1] u[0,2] …
u[1,0] u[1,1] u[1,2] …
u[2,0] u[2,1] u[2,2] …
…
(u[1,2]
– u[1,0])/2
u
∂u/∂x 右 – 左
拡散⽅方程式
l  物質や熱の拡散を⽀支配する⽅方程式
∂u
∂t
= D
∂2
u
∂x2
+
∂2
u
∂y2
"
#
$
%
&
'
= D∇2
u
u[0,0] u[0,1] u[0,2] …
u[1,0] u[1,1] u[1,2] …
u[2,0] u[2,1] u[2,2] …
…
(u[0,1]+u[2,1]+u[1,0]+u[1,2] – 4*u[1,1])
∇2
u上下左右 – 4*⾃自分
拡散⽅方程式
l  物質や熱の拡散を⽀支配する⽅方程式
∂u
∂t
= D
∂2
u
∂x2
+
∂2
u
∂y2
"
#
$
%
&
'
= D∇2
u
u[0,0] u[0,1] u[0,2] …
u[1,0] u[1,1] u[1,2] …
u[2,0] u[2,1] u[2,2] …
…
(u[0,1]+u[2,1]+u[1,0]+u[1,2] – 4*u[1,1])
∇2
u
このカーネルで
Convolution_2d
0 1 0
1 -4 1
0 1 0
t = 0 t = 10 t = 100
cupy
カーネルを⼿手打ち
場外はとりあえず0で
偏微分⽅方程式を解く流流れ
l  ニューラルネット的に
Convolution
Element-
wise
Boudary
condition
∂ζ
∂t
= −ux
∂ζ
∂x
−uy
∂ζ
∂y
+ν∇2
ζ
ζ +
周期境界
固定境界
など
反応拡散⽅方程式
l  拡散項以外の部分をElementwiseカーネルで書く
反応拡散⽅方程式
l  境界条件
l  メインループの内側
反応拡散⽅方程式
ポアソン⽅方程式を解く
l  ポアソン⽅方程式
l  ρが与えられた時にψを求める問題
–  電荷→電位
–  質量量分布→重⼒力力ポテンシャル
–  理理想流流体の定常解(ρは湧き出し)
–  拡散⽅方程式の定常解(ρは湧き出し)
∇2
ψ = ρ +2
-1
ポアソン⽅方程式を解く
l  ヤコビ法
–  次の操作を反復復する(αは適当な係数)
                                                              ここが0になると収束する
∇2
ψ = ρ
ψ ←ψ +α(ρ − ∇2
ψ)
さっきの拡散⽅方程式と同じconvolution
正解に近いx0から始めれば、少ない数の反復復でOK
ポアソン⽅方程式を解く
l  ヤコビ法
–  次の操作を反復復する(αは適当な係数)
                                                              ここが0になると収束する
∇2
ψ = ρ
ψ ←ψ +α(ρ − ∇2
ψ)
さっきの拡散⽅方程式と同じconvolution
正解に近いx0から始めれば、少ない数の反復復でOK
ポアソン⽅方程式を解く
l  ヤコビ法
–  次の操作を反復復する(αは適当な係数)
                                                              ここが0になると収束する
∇2
ψ = ρ
ψ ←ψ +α(ρ − ∇2
ψ)
さっきの拡散⽅方程式と同じconvolution
正解に近いx0から始めれば、少ない数の反復復でOK
ポアソン⽅方程式を解く
l  ヤコビ法
–  次の操作を反復復する(αは適当な係数)
                                                              ここが0になると収束する
∇2
ψ = ρ
ψ ←ψ +α(ρ − ∇2
ψ)
さっきの拡散⽅方程式と同じconvolution
正解に近いx0から始めれば、少ない数の反復復でOK
流流体⽅方程式
l  こんなのを解きたい(https://ja.wikipedia.org/wiki/渦度度・流流れ関数法)
ポアソン⽅方程式
この項は拡散⽅方程式
Ψは、微分すると流流速uが出てくるような量量として定義
ポアソン⽅方程式より、ζとuは次の関係にある
ζ = rotu =
duy
dx
−
dux
dy
こういう点で
渦度度ζは⼤大きい
流流速u
流流体⽅方程式
l  渦度度輸送⽅方程式を⼀一部抜粋
∂ζ
∂t
= −ux
∂ζ
∂x
この式の意味は?
流流体⽅方程式
l  渦度度輸送⽅方程式を⼀一部抜粋
x
ζ(x, t)
流流速ux
∂ζ
∂t
= −ux
∂ζ
∂x
この点でのζ(x, t)が、t+Δtではどれだけ増加するか?
流流体⽅方程式
l  渦度度輸送⽅方程式を⼀一部抜粋
x
ζ(x, t)
ζ(x, t+Δt)
流流速ux
uxΔt
∂ζ
∂t
= −ux
∂ζ
∂x
−ux
∂ζ
∂x
Δt
保存量量ζが流流速uで流流れる現象を表した⽅方程式
流流体⽅方程式を解く
l  道具は揃った?
0 0 0
−0.5 0 0.5
0 0 0
0 −0.5 0
0 0 0
0 0.5 0
0 1 0
1 −4 1
0 1 0
ポアソン⽅方程式→ヤコビ法
d/dxのカーネル d/dyのカーネル ∇2のカーネル
Poissonを解いて
Ψを求める
(Jacobi法)
Ψ, ζのx, y微分,
∇2ζを
Convで求める
Element-wiseに
渦度度輸送⽅方程式を
Δt進める
流流体⽅方程式を解く
l  道具は揃った?
0 0 0
−0.5 0 0.5
0 0 0
0 −0.5 0
0 0 0
0 0.5 0
0 1 0
1 −4 1
0 1 0
ポアソン⽅方程式→ヤコビ法
d/dxのカーネル d/dyのカーネル ∇2のカーネル
Poissonを解いて
Ψを求める
(Jacobi法)
Ψ, ζのx, y微分,
∇2ζを
Convで求める
Element-wiseに
渦度度輸送⽅方程式を
Δt進める
流流体⽅方程式を解く
l  道具は揃った?
0 0 0
−0.5 0 0.5
0 0 0
0 −0.5 0
0 0 0
0 0.5 0
0 1 0
1 −4 1
0 1 0
ポアソン⽅方程式→ヤコビ法
d/dxのカーネル d/dyのカーネル ∇2のカーネル
ζの初期値
500*500の[-10,10]⼀一様分布をガウシアン
カーネルで平滑滑化したもの
流流体⽅方程式を解く
l  道具は揃った?
100ステップ 200ステップ
そして
NaNへ
変な振動が
成⻑⾧長していく!
流流体は、どんどん解が
鈍っていく拡散⽅方程式
などと⽐比べて不不安定で
ある
∂ρ
∂t
= −ux
∂ρ
∂x
−uy
∂ρ
∂y に従うインクを可視化している
流流体⽅方程式の精度度向上:差分の精度度向上
l  ラプラシアン2次精度度→4次精度度
l  オイラー法(1次)→中点法(2次)
0 1 0
1 −4 1
0 1 0
0.2 0.8 0.2
0.8 −4 0.8
0.2 0.8 0.2
x = x_init
for i in xrange(T/dt):
dxdt = f(x)
x = x + dt * dxdt
x = x_init
for i in xrange(T/dt):
dxdt = f(x)
x_ = x + 0.5 * dt * dxdt
dxdt_ = f(x_)
x = x + dt * dxdt_
流流体⽅方程式の精度度向上:⾵風上差分
l  今までのdxカーネルは、⾵風下の情報も使っている
–  しかし⾵風下からは情報は流流れてこない
l  ⾵風上だけから情報を取ってくるようにしたい!
0 0 0
−0.5 0 0.5
0 0 0
⾵風上        ux ⾵風下
0 0 0
−1 1 0
0 0 0
0 0 0
0 −1 1
0 0 0
uxが正の時
(右向きの⾵風)
uxが負の時
(左向きの⾵風)
流流体⽅方程式の精度度向上:⾵風上差分
l  今までのdxカーネルは、⾵風下の情報も使っている
–  しかし⾵風下からは情報は流流れてこない
l  ⾵風上だけから情報を取ってくるようにしたい!
0 0 0
−0.5 0 0.5
0 0 0
⾵風上        ux ⾵風下
0 0 0
−1 1 0
0 0 0
0 0 0
0 −1 1
0 0 0
uxが正の時
(右向きの⾵風)
uxが負の時
(左向きの⾵風)
両⽅方のカーネルを計算しておいて、
流流速の符号に応じて⽚片⽅方を⽤用いる
流流体⽅方程式の精度度向上:⾵風上差分
l  河村・桑原スキーム(3次精度度⾵風上差分)
0 0 0 0 0
0 0 0 0 0
1/ 6 −6 / 6 3/ 6 2 / 6 0
0 0 0 0 0
0 0 0 0 0
0 0 0 0 0
0 0 0 0 0
0 −2 / 6 −3/ 6 6 / 6 −1/ 6
0 0 0 0 0
0 0 0 0 0
uxが正の時
(右向きの⾵風)
uxが負の時
(左向きの⾵風)
流流体⽅方程式実験1
流流体⽅方程式実験2
l  せっかくのChainerなのでBackpropを使ってみる
–  実はすべて微分可能な操作
Poissonを解いて
Ψを求める
(Jacobi法)
Ψ, ζのx, y微分,
∇2ζを
Convで求める
Element-wiseに
渦度度輸送⽅方程式を
Δt進める
10回convと
basic_mathしてるだけ
流流体⽅方程式実験2
l  適切切なζの初期値を勾配降降下法で求める
100ステップの
流流体時間発展
⽬目標との誤差をbackwardして
初期値のζを更更新する
⽬目標
これをやるだけ
流流体⽅方程式実験2
⾵風上差分だけ
backwardを書く
必要あり
流流体⽅方程式実験2
l  ChainerからPFNへ
まとめ
l  ふと微分⽅方程式を解きたくなったら?
–  →Chainer

Chainerで流体計算