1#include "SurfaceEnergyForce.h"
5 template<typename TDataType>
6 SurfaceEnergyForce<TDataType>::SurfaceEnergyForce()
7 : ParticleApproximation<TDataType>()
9 this->varKernelType()->setCurrentKey(ParticleApproximation<TDataType>::EKernelType::KT_Smooth);
12 template<typename TDataType>
13 SurfaceEnergyForce<TDataType>::~SurfaceEnergyForce()
15 mFreeSurfaceEnergy.clear();
19 template<typename Real, typename Coord, typename Kernel>
20 __global__ void ST_ComputeSurfaceEnergy(
21 DArray<Real> energyArr,
23 DArrayList<int> neighbors,
25 Real samplingDistance,
29 int pId = threadIdx.x + (blockIdx.x * blockDim.x);
30 if (pId >= posArr.size()) return;
32 Real V_0 = samplingDistance * samplingDistance * samplingDistance;
34 Real total_weight = Real(0);
37 Coord pos_i = posArr[pId];
38 List<int>& nbrIds_i = neighbors[pId];
39 int nbSize = nbrIds_i.size();
40 for (int ne = 0; ne < nbSize; ne++)
43 Real r = (pos_i - posArr[j]).norm();
47 Real weight = -V_0 * gradient(r, smoothingLength, scale);
48 total_weight += weight;
49 dir_i += (posArr[j] - pos_i) * (weight / r);
53 total_weight = total_weight < EPSILON ? 1.0f : total_weight;
54 Real absDir = dir_i.norm() / total_weight;
56 energyArr[pId] = absDir * absDir;
60 template<typename Real, typename Coord, typename Kernel>
61 __global__ void ST_ComputeSurfaceTension(
63 DArray<Real> energyArr,
65 DArrayList<int> neighbors,
67 Real samplingDistance,
74 int pId = threadIdx.x + (blockIdx.x * blockDim.x);
75 if (pId >= posArr.size()) return;
77 Real V_0 = samplingDistance * samplingDistance * samplingDistance;
79 //A hack in using 1000000, to be refined in the future
80 Real ceof = 1000000 * kappa;
84 Coord pos_i = posArr[pId];
85 List<int>& nbrIds_i = neighbors[pId];
86 int nbSize = nbrIds_i.size();
87 for (int ne = 0; ne < nbSize; ne++)
90 Real r = (pos_i - posArr[j]).norm();
94 Coord F_ij = V_0 * V_0 * gradient(r, smoothingLength, scale) * (posArr[j] - pos_i) * (1.0f / r);
99 velArr[pId] -= dt * ceof * F_i / (density * V_0);
102 template<typename TDataType>
103 void SurfaceEnergyForce<TDataType>::compute()
105 Real kappa = this->varKappa()->getValue();
106 Real rho = this->varRestDensity()->getValue();
108 auto dt = this->inTimeStep()->getValue();
110 auto& pos = this->inPosition()->constData();
111 auto& vel = this->inVelocity()->getData();
112 auto& neighbors = this->inNeighborIds()->constData();
114 auto h = this->inSmoothingLength()->getValue();
115 auto d = this->inSamplingDistance()->getValue();
117 int num = pos.size();
119 if (num != mFreeSurfaceEnergy.size())
120 mFreeSurfaceEnergy.resize(num);
122 cuFirstOrder(num, this->varKernelType()->getDataPtr()->currentKey(), this->mScalingFactor,
123 ST_ComputeSurfaceEnergy,
130 cuFirstOrder(num, this->varKernelType()->getDataPtr()->currentKey(), this->mScalingFactor,
131 ST_ComputeSurfaceTension,
143 DEFINE_CLASS(SurfaceEnergyForce);