Article Physics & Mechanics · ≈ ⏱ 12 min read

SPH kernel functions: a deep-dive into Poly6, Spiky, Viscosity and Cubic-Spline

Every Smoothed Particle Hydrodynamics simulation lives or dies by its choice of kernel. The same physics, evaluated with the wrong weighting function, either explodes into noise or clumps into unphysical blobs. Here is why kernels matter, and how to pick one.

TL;DR: SPH needs a different kernel for each operator: Poly6 for density (smooth but zero gradient at r=0), Spiky for pressure force (non-zero gradient prevents particle overlap), and the Viscosity kernel for its stable Laplacian. Mixing them up causes particle clumping; the cubic-spline/Wendland kernels unify all three for astrophysical codes.

1. The role of a kernel in SPH

У SPH будь-яка фізична величина (густина, тиск, швидкість) обчислюється не в точці, а як зважена сума значень сусідніх частинок. Ядро W(r, h) — це вагова функція, яка визначає, наскільки сильно частинка на відстані r впливає на центральну частинку в межах радіуса згладжування h (smoothing length).

SPH interpolation of a field A A(r) ≈ Σⱼ mⱼ · (Aⱼ / ρⱼ) · W(r − rⱼ, h)

Ключове спостереження: ядро — це не просто «вага за відстанню». Різні фізичні величини потребують різних похідних ядра: густина використовує саме W, тиск — градієнт ∇W, а в'язкість — лапласіан ∇²W. Погано підібране ядро для градієнта призводить до нестабільності навіть якщо густина обчислюється коректно.

Why this matters

Одне й те саме ядро для всіх операторів (як робили у ранніх реалізаціях) призводить до частинкового кластерингу — «particle clumping» — коли частинки злипаються в парах на відстані, де градієнт ядра дорівнює нулю. Це фундаментальна причина, чому сучасні реалізації SPH використовують окремі ядра для тиску (Spiky) і в'язкості (Viscosity).

2. Mathematical requirements

Щоб ядро було коректним для SPH, воно повинно задовольняти чотирьом умовам:

  • Нормалізація: ∫ W(r, h) dr = 1 у всьому просторі — інакше інтерполяція зміщує величини систематично.
  • Компактний носій (compact support): W(r, h) = 0 при r > h — це дозволяє обмежити пошук сусідів радіусом h і використовувати просторове хешування замість O(N²) перебору.
  • Додатність: W(r, h) ≥ 0 всюди — фізичні величини на кшталт густини не можуть бути від'ємними.
  • Зменшення з відстанню (monotonic decay): найближчі сусіди повинні впливати сильніше за дальні, а на межі носія (r = h) ядро і, бажано, його похідна плавно йдуть до нуля (C¹-неперервність), щоб уникнути розривів сили.
Normalization constraint ∫₀ʰ W(r, h) · 4πr² dr = 1    (3D, spherical shells)

Нормувальна константа σ (наприклад, 315/(64πh⁹) для Poly6 у 3D) виводиться саме з цієї умови і залежить від розмірності простору (1D/2D/3D мають різні константи).

3. Poly6 kernel

Poly6 (запропоновано Müller et al., 2003) — гладка поліноміальна функція, ідеальна для обчислення густини, де важлива гладкість, а не точність градієнта біля центру.

Poly6 kernel (3D) W_poly6(r, h) = 315/(64πh⁹) · (h² − r²)³,   0 ≤ r ≤ h
W_poly6(r, h) = 0,   r > h

Проблема Poly6 — його градієнт прямує до нуля при r → 0:

Poly6 gradient ∇W_poly6(r, h) = −945/(32πh⁹) · (h² − r²)² · r

Коли r → 0, множник r обнуляє весь градієнт. Це означає, що для двох частинок, які злиплись впритул, сила відштовхування, обчислена через градієнт Poly6, зникає — саме тому це ядро не можна використовувати для тиску. Використання Poly6 лише для густини — стандартна практика.

4. Spiky kernel

Spiky-ядро вирішує проблему нульового градієнта біля центру за рахунок «гострої» вершини (звідси назва) — похідна лишається ненульовою навіть при r → 0.

Spiky kernel (3D) W_spiky(r, h) = 15/(πh⁶) · (h − r)³,   0 ≤ r ≤ h
Spiky gradient — used for pressure force ∇W_spiky(r, h) = −45/(πh⁶) · (h − r)² · (r̂)

При r → 0 градієнт прямує до −45/(πh⁶) · h²ненульова константа, яка забезпечує сильне відштовхування частинок, що злиплись. Це ключова властивість, яка запобігає взаємопроникненню частинок під високим тиском.

Symmetrized pressure force

На практиці силу тиску симетризують, щоб уникнути порушення третього закону Ньютона через асиметрію тиску pᵢ ≠ pⱼ: Fᵢ = −Σⱼ mⱼ · (pᵢ + pⱼ)/(2ρⱼ) · ∇W_spiky(rᵢ − rⱼ, h). Це гарантує рівність дії й протидії з точністю до заокруглення.

5. Viscosity kernel

В'язкість вимагає лапласіана поля швидкості (∇²W), а не градієнта. Ні Poly6, ні Spiky не дають монотонного, стабільного лапласіана — Müller et al. запропонували окреме ядро саме для цієї мети.

Viscosity kernel (3D) W_visc(r, h) = 15/(2πh³) · (−r³/(2h³) + r²/h² + h/(2r) − 1),   0 ≤ r ≤ h
Viscosity Laplacian — used for viscous force ∇²W_visc(r, h) = 45/(πh⁶) · (h − r)

Лапласіан цього ядра лінійний і завжди додатний у межах носія — це гарантує, що в'язка сила завжди діє в напрямку вирівнювання швидкостей (як фізична в'язкість і повинна), без паразитних осциляцій, які виникали б із лапласіана Poly6 чи Spiky.

Viscous force between particles i, j Fᵢ_visc = μ · Σⱼ mⱼ · (vⱼ − vᵢ)/ρⱼ · ∇²W_visc(rᵢ − rⱼ, h)

6. Cubic-spline (B-spline) kernel

Ядро Мональхана-Ласерсона (кубічний B-сплайн) — стандарт у науковій астрофізичній SPH (GADGET, PHANTOM), на відміну від ігрового набору Poly6/Spiky/Viscosity. Воно кусочно-визначене на двох інтервалах і дає один набір формул для густини, градієнта і лапласіана — з коректною поведінкою в усіх трьох випадках:

Cubic spline kernel (3D, q = r/h) W(q, h) = σ₃/h³ ·
   1 − 3/2·q² + 3/4·q³,   0 ≤ q ≤ 1
   1/4·(2 − q)³,   1 ≤ q ≤ 2
   0,   q > 2
(σ₃ = 1/π у 3D)

На відміну від Poly6/Spiky/Viscosity, кубічний сплайн C²-гладкий (неперервна друга похідна) — важливо для довгих астрофізичних симуляцій, де накопичення похибки на мільярдах кроків критичне. Носій охоплює 2h замість h — тому потребує більше сусідів (≈ 50 у 3D) для тієї ж роздільної здатності.

Wendland kernels — modern alternative

У сучасних SPH-кодах (SPHysics, DualSPHysics) кубічний сплайн часто заміняють ядрами Wendland (C2, C4, C6) — вони не мають «pairing instability» кубічного сплайна при малому числі сусідів і швидше згасають, зменшуючи вартість пошуку сусідів.

7. Kernel comparison

Kernel Best for Support Grad at r→0 Smoothness
Poly6 Density ρ h 0 (bad for force)
Spiky Pressure force h Non-zero ✅ C⁰ at r=0
Viscosity Viscous force (Laplacian) h Monotonic ∇²
Cubic spline Astrophysical SPH (all ops) 2h Non-zero ✅
Wendland C2 Large-N modern SPH h Non-zero ✅ C² compact

8. Common pitfalls

Using one kernel for everything

Найпоширеніша помилка новачків — обчислювати і густину, і тиск, і в'язкість через градієнт одного й того ж Poly6. Результат: частинки, злипаючись, не відштовхуються (градієнт → 0), і симуляція «замерзає» в купки замість плавної течії рідини.

Wrong normalization constant for dimensionality

Константи 315/(64πh⁹) для Poly6 і 15/(πh⁶) для Spiky коректні лише в 3D. Для 2D-симуляцій (площинна рідина в canvas/WebGL side-view) потрібні окремі нормувальні множники — інакше загальна маса системи «пливе».

Smoothing length too small or too large

Занадто мале h → мало сусідів → шумна, нестабільна апроксимація (недостатньо статистики). Занадто велике h → надмірне згладжування, втрата деталей, вища вартість O(N·k). Практичне правило: h таке, щоб у носії було 20–40 сусідів у 2D, 30–60 у 3D.

9. Псевдокод

Три ядра в одному об'єкті (JS)

// Ядра SPH — 2D варіант (canvas / WebGL side simulations)
function makeKernels(h) {
  const h2 = h * h, h6 = h**6, h9 = h**9;

  return {
    // Poly6 — тільки для густини
    poly6(r) {
      if (r > h) return 0;
      const diff = h2 − r * r;
      return (315 / (64 * Math.PI * h9)) * diff**3;
    },

    // Spiky gradient — сила тиску (ненульовий градієнт при r→0)
    spikyGrad(r, dir) {
      if (r > h || r === 0) return [0, 0];
      const coeff = −45 / (Math.PI * h6) * (h − r)**2;
      return [coeff * dir[0], coeff * dir[1]];
    },

    // Viscosity Laplacian — гарантовано монотонний, стабільний
    viscLaplacian(r) {
      if (r > h) return 0;
      return (45 / (Math.PI * h6)) * (h − r);
    }
  };
}
▶ Live Demo

See SPH kernels in action

Симуляція рідини використовує Poly6 для густини, Spiky для тиску і Viscosity-ядро для в'язкості — саме те розділення, яке описане в цій статті.

⭐ SPH Fluid 🔵 Molecular Dynamics

🔗 Related Simulations

💧SPH Fluid 🌀Vorticity 🔵Molecular Dynamics N-Body