Program Listing for File SPHKernels.h
↰ Return to documentation for file (PositionBasedDynamics/SPHKernels.h)
#ifndef SPHKERNELS_H
#define SPHKERNELS_H
#define _USE_MATH_DEFINES
#include <math.h>
#include "Common/Common.h"
#include <algorithm>
#define NO_DISTANCE_TEST
namespace PBD
{
class CubicKernel
{
protected:
static Real m_radius;
static Real m_k;
static Real m_l;
static Real m_W_zero;
public:
static Real getRadius() { return m_radius; }
static void setRadius(Real val)
{
m_radius = val;
static const Real pi = static_cast<Real>(M_PI);
const Real h3 = m_radius*m_radius*m_radius;
m_k = static_cast<Real>(8.0) / (pi*h3);
m_l = static_cast<Real>(48.0) / (pi*h3);
m_W_zero = W(Vector3r(0.0, 0.0, 0.0));
}
public:
//static unsigned int counter;
static Real W(const Vector3r &r)
{
//counter++;
Real res = 0.0;
const Real rl = r.norm();
const Real q = rl/m_radius;
#ifndef NO_DISTANCE_TEST
if (q <= 1.0)
#endif
{
if (q <= 0.5)
{
const Real q2 = q*q;
const Real q3 = q2*q;
res = m_k * (static_cast<Real>(6.0)*q3- static_cast<Real>(6.0)*q2+ static_cast<Real>(1.0));
}
else
{
res = m_k * (static_cast<Real>(2.0)*pow(static_cast<Real>(1.0)-q,3));
}
}
return res;
}
static Vector3r gradW(const Vector3r &r)
{
Vector3r res;
const Real rl = r.norm();
const Real q = rl / m_radius;
#ifndef NO_DISTANCE_TEST
if (q <= 1.0)
#endif
{
if (rl > 1.0e-6)
{
const Vector3r gradq = r * ((Real) 1.0 / (rl*m_radius));
if (q <= 0.5)
{
res = m_l*q*((Real) 3.0*q - (Real) 2.0)*gradq;
}
else
{
const Real factor = static_cast<Real>(1.0) - q;
res = m_l*(-factor*factor)*gradq;
}
}
}
#ifndef NO_DISTANCE_TEST
else
res.zero();
#endif
return res;
}
static Real W_zero()
{
return m_W_zero;
}
};
}
#endif