[ Fluid Simulation ] 02. 파동 난류 표현 (Wave Turbulence)
🌊 파동 난류 (Wave Turbulence)
기존의 유체 시뮬레이션은 표면에서의 파동 표현이 자세하게 표현되지 않는다. 따라서 FLIP 기법에 추가적인 시각적 세부 표현을 더하기 위해 파동 난류 표현을 진행한다.
파동 난류는 입자 기반 액체 시뮬레이션의 후처리 과정으로, 다음의 세 가지 과정으로 나뉜다:
1. 난류 입자의 초기화
2. 난류 입자의 표면 유지
3. 파동 시뮬레이션
🎯 난류 입자의 초기화 (Initialize)
먼저, 기존 시뮬레이션의 각 coarse 입자에 대해 $\lambda_c$ 반경을 갖는 구를 생성하고, 균일하게 sampling 한다:
다른 구에 포함되지 않은 입자만 남기면 surface의 fine-scale 입자가 생성된다:
🧩 난류 입자의 표면 유지 과정 (Surface Maintenance)
표면 유지 과정의 경우 다음 세 가지 과정을 거친다:
난류 입자의 이류
표면의 법선 벡터 계산
표면의 정규화 과정
💨 난류 입자의 이류 (Advection of Turbulence Particle)
난류 입자의 이류는 주변의 Base Simulation 입자의 움직임을 가중치 평균한 값을 통해 진행된다:
\[
\mathbf{x}_i^n \leftarrow \mathbf{x}_i^{n-1} + \sum_{k \in \mathcal{C}} W_i^{2\lambda_c}(\mathbf{X}_k) \left( \mathbf{X}_k^n - \mathbf{X}_k^{n-1} \right)
\]
여기서 $X_i$ 는 Base Simulation 입자의 위치 값, $x_i$는 Turbulence Particle 입자의 위치 값, $C$ 는 coarse-scale particle(=base simulation 입자), $F$ 는 fine-scale particle(= turbulence 입자)를 의미한다.
또한, 위 식에서 가중치를 의미하는 $W_i^{2 \lambda_c}$ 는 등방성 커널로 아래와 같다:
\[
K_i^\delta(\mathbf{x}_j) =
\begin{cases}
1 - \|\mathbf{x}_i - \mathbf{x}_j\| / \delta, & \text{if } \|\mathbf{x}_i - \mathbf{x}_j\| < \delta \\
0, & \text{otherwise}
\end{cases}
\tag{1}
\]
\[
\rho_j^\delta = \sum_{k \in \mathcal{F}} K_j^\delta(\mathbf{x}_k)
\tag{2}
\]
\[
w_i^\delta(\mathbf{x}_j) = \frac{K_i^\delta(\mathbf{x}_j)}{\rho_j^\delta}
\tag{3}
\]
\[
W_i^\delta(\mathbf{x}_j) = \frac{w_i^\delta(\mathbf{x}_j)}{\sum_{k \in \mathcal{F}} w_i^\delta(\mathbf{x}_k)}
\tag{4}
\]
이때 각 식이 의미하는 바는 다음과 같다:
식(1): 이웃 입자와의 거리와 반비례하는 가중치 설정
식(2): 이웃 입자 j에 대해 주변 가중치를 합산하여 밀도 계산
식(3): 밀도로 normalize -> 밀도와 반비례 관계
식(4): 입자 i가 입자 j로부터 받는 영향(가중치)
최종적으로, 아래와 같이 밀도 차이가 있는 상황에서 밀도에 따른 가중치의 편향성을 제거한 값을 계산한다:
이류 과정 이후에 fine-scale 입자는 coarse simulation의 동역학과 일치하지 않을 수 있다. 이를 예방하기 위해 Surface Constraints를 생성하여 보정한다.
이때, 메타볼(Metaball) 레벨셋을 활용하여 법선 벡터(Gradient)를 계산하고 제약조건 투영을 활용해 coarse-scale 입자 주변에 위치가 유지되도록 한다:
\[
\mathbf{x}_i \leftarrow
\begin{cases}
\mathbf{x}_i - (R - r) \cdot \phi(\mathbf{x}_i) \cdot \mathbf{g}_i & \text{if } \phi(\mathbf{x}_i) < 0 \\
\mathbf{x}_i - (R - r) \cdot (\phi(\mathbf{x}_i) - 1) \cdot \mathbf{g}_i & \text{if } \phi(\mathbf{x}_i) > 1 \\
\mathbf{x}_i & \text{otherwise}
\end{cases}
\]
📐 표면의 법선 벡터 계산 (Compute Surface Normal)
앞서, 메타볼 레벨셋을 활용해 계산한 $\nabla\phi$를 활용해 tangent와 bitangent를 계산한다. 이후, 해당 좌표계에 대한 $\lambda_c$ 반경 내부 이웃의 최소제곱평면을 활용한다:
🧽 표면 정규화 (Surface Regularization)
표면 정규화는 다음 세 가지 과정으로 나눌 수 있다.
법선 벡터 방향 정규화
탄젠트 방향 정규화
삽입/삭제
법선 벡터 방향 정규화 (Regularization Along the Normal)
표면의 smoothing을 위해 진행되는 과정으로, 법선 벡터 방향을 따라 점들을 이동시키는 과정이 필요하다.
먼저, 법선 벡터와 $x_j - x_i$가 포함된 평면 위의 각 점 $i, \ j$에 같은 거리에 있고, 각 법선 벡터에 수직인 원을 찾는다:
이후, 다음 공식을 활용해 투영을 진행한다:
\[
\mathrm{proj}_{i,j} = \mathbf{n}_i \frac{ \left( \mathbf{n}_i + \mathbf{n}_j^\star \right) \cdot \left( \mathbf{x}_i - \mathbf{x}_j \right)}{2 \, \mathbf{n}_i \cdot \left( \mathbf{n}_i + \mathbf{n}_j^\star \right)}
\]
\[
\mathbf{x}_i \leftarrow \mathbf{x}_i + \sum_{j \in \mathcal{F}} W_i^{\lambda_c}(\mathbf{x}_j) \, \mathrm{proj}_{i,j}
\]
최종적으로 이웃한 점이 원의 표면에 투영된다.
탄젠트 방향 정규화 (Regularization Along the Tangent)
fine-scale 입자의 밀도를 유지하기 위해 탄젠트 방향 정규화를 진행한다. 이는 다음 공식에 따라 수행된다:
\[
\mathbf{x}_i \leftarrow \mathbf{x}_i + 0.5 \lambda_f
\sum_{j \in \mathcal{F}} W_i^{\lambda^f}(\mathbf{x}_j) \, \mathrm{TN}_i(\mathbf{x}_j - \mathbf{x}_i)
\]
삽입/삭제 (Insertion/Deletion)
마찬가지로 표면의 밀도를 유지하기 위해 fine-scale 입자의 삽입/삭제 과정을 진행한다.
입자가 삭제되는 경우는 다음과 같다:
입자가 삽입되는 경우는 다음과 같다:
🌊 파동 시뮬레이션 (Wave Simulation)
파동 시뮬레이션의 경우, 다음 세 가지 과정을 거친다:
곡률 계산
파동 생성
표면 파동 전파
🌀 곡률 계산 (Compute Curvature)
곡률은 파동의 활발한(병합/분리) 부분을 판단하는 데에 사용되며, 다음 공식에 의해 계산된다:
\[
c_i = \sum_{j \in \mathcal{F}} W_i^{\lambda_c}(\mathbf{x}_j)
\left( \mathbf{n}_i \cdot (\mathbf{x}_i - \mathbf{x}_j) \right)
\]
📡 파동 생성 (Oscillatory Wave Seeding)
파동은 곡률이 높은 입자로부터 코사인 파동 생성을 시작하며, 불안정한 지점에서는 파동을 제한하고, 다양한 주파수를 중첩하여 복합적인 파형을 생성한다.
- line 2: 곡률이 너무 높은 지역에선 질량 보존이 안되고, 급격한 변화(불안정)하기 때문에 임계값을 통해 제한
🔁 표면 파동 전파 (Evolve Surface Wave)
표면 파동의 전파는 1차원 파동 방정식을 사용한다:
$$
\Huge \frac{\partial^2 u}{\partial t^2} = c^2 \nabla^2 u
$$
이때, 1차원 파동 방정식은 $u(x,t)$에 대한 편미분 방정식으로, $c$는 파동의 속도, $u(x,t)$ 는 시각 $t$, 위치 $x$ 에서의 파동의 진폭을 나타낸다.
알고리즘은 다음과 같다:
- line 9-10: 다음 프레임의 $h$를 계산($h$의 전파) 그리고, $s_i$를 뺀다.
이때, 코사인 osciilator에 의한 seed 값 $s_i$ 값을 계산한 뒤, $h = d + s$를 통해 파동의 높이를 계산하고,
$h$를 파동 방정식을 통해 전파 시킨 뒤, $s$ 값을 빼서 실제 보이는 파동의 높이 $d = h-s$를 계산하여 더욱 역동적인 파동을 표현한다.
💻 구현 (Implementation)
전체 프레임워크는 다음과 같은 과정으로 이루어졌다:
이때, Base Simulation 기법은 FLIP을 활용했다.
또한, 입자로 출력되는 결과를 삼각형 메시로 구성하기 위해 Marching Cube 기법을 활용하였으며, 이때 레벨셋을 구성하기 위해 입자의 밀도 값을 사용했다.
📈 결과 (Results)
참고자료: