PeriDyno 1.0.0
Loading...
Searching...
No Matches
SemiAnalyticalSummationDensity.cu
Go to the documentation of this file.
1#include "SemiAnalyticalSummationDensity.h"
2
3#include "IntersectionArea.h"
4
5namespace dyno
6{
7 IMPLEMENT_TCLASS(SemiAnalyticalSummationDensity, TDataType)
8
9 template<typename TDataType>
10 SemiAnalyticalSummationDensity<TDataType>::SemiAnalyticalSummationDensity()
11 : ParticleApproximation<TDataType>()
12 , m_factor(Real(1))
13 {
14 this->varRestDensity()->setValue(Real(1000));//1000
15
16 auto callback = std::make_shared<FCallBackFunc>(
17 std::bind(&SemiAnalyticalSummationDensity<TDataType>::calculateParticleMass, this));
18
19 this->varRestDensity()->attach(callback);
20 this->inSamplingDistance()->attach(callback);
21 }
22
23 template<typename TDataType>
24 void SemiAnalyticalSummationDensity<TDataType>::compute()
25 {
26 auto ts = this->inTriangleSet()->constDataPtr();
27 auto& triVertex = ts->getPoints();
28 auto& triIndex = ts->getTriangles();
29
30 int p_num = this->inPosition()->getDataPtr()->size();
31 int n_num = this->inNeighborIds()->getDataPtr()->size();
32 int t_num = triIndex.size();
33 int tn_num = this->inNeighborTriIds()->getDataPtr()->size();
34
35 //printf("tn_num: %d\n", tn_num);
36
37 if (p_num != n_num ) {
38 Log::sendMessage(Log::Error, "The input array sizes of DensitySummation are not compatible!");
39 return;
40 }
41
42 if (this->outDensity()->size() != p_num) {
43 this->outDensity()->resize(p_num);
44 }
45
46 compute(
47 this->outDensity()->getData(),
48 this->inPosition()->getData(),
49 triIndex,
50 triVertex,
51 this->inNeighborIds()->getData(),
52 this->inNeighborTriIds()->getData(),
53 this->inSmoothingLength()->getData(),
54 m_particle_mass,
55 this->inSamplingDistance()->getData());
56 }
57
58
59 template<typename TDataType>
60 void SemiAnalyticalSummationDensity<TDataType>::compute(DArray<Real>& rho)
61 {
62 auto ts = this->inTriangleSet()->constDataPtr();
63 auto& triVertex = ts->getPoints();
64 auto& triIndex = ts->getTriangles();
65
66 compute(
67 rho,
68 this->inPosition()->getData(),
69 triIndex,
70 triVertex,
71 this->inNeighborIds()->getData(),
72 this->inNeighborTriIds()->getData(),
73 this->inSmoothingLength()->getData(),
74 m_particle_mass,
75 this->inSamplingDistance()->getData());
76 }
77
78 template<typename Real, typename Coord, typename Kernel>
79 __global__ void SD_ComputeDensity(
80 DArray<Real> rhoArr,
81 DArray<Coord> posArr,
82 DArrayList<int> neighbors,
83 Real smoothingLength,
84 Real mass,
85 Real sampling_distance,
86 Kernel kernel,
87 Real scale)
88 {
89 int pId = threadIdx.x + (blockIdx.x * blockDim.x);
90 if (pId >= posArr.size()) return;
91
92 SpikyKernel<Real> kern;
93 Real r;
94 Real rho_i = Real(0);
95 Real rho_tmp(0);
96 Coord pos_i = posArr[pId];
97
98 List<int>& list_i = neighbors[pId];
99
100 int nbSize = list_i.size();
101 for (int ne = 0; ne < nbSize; ne++)
102 {
103 int j = list_i[ne];
104 r = (pos_i - posArr[j]).norm();
105 rho_i += mass * kernel(r, smoothingLength, scale);
106 }
107
108 rhoArr[pId] = rho_i;
109 }
110
111 template<typename Real, typename Coord, typename Kernel>
112 __global__ void SD_BoundaryIntegral(
113 DArray<Real> rhoArr,
114 DArray<Coord> posArr,
115 DArray<TopologyModule::Triangle> Tri,
116 DArray<Coord> positionTri,
117 DArrayList<int> neighborsTri,
118 Real smoothingLength,
119 Real mass,
120 Kernel kernel,
121 Real scale)
122 {
123 int pId = threadIdx.x + (blockIdx.x * blockDim.x);
124 if (pId >= rhoArr.size()) return;
125
126 Real rho_i = Real(0);
127 Coord pos_i = posArr[pId];
128
129 List<int>& nbrTriIds_i = neighborsTri[pId];
130 int nbSizeTri = nbrTriIds_i.size();
131 if (nbSizeTri > 0)
132 {
133 for (int ne = 0; ne < nbSizeTri; ne++)
134 {
135 int j = nbrTriIds_i[ne];
136
137
138 Triangle3D t3d(positionTri[Tri[j][0]], positionTri[Tri[j][1]], positionTri[Tri[j][2]]);
139 Plane3D PL(positionTri[Tri[j][0]], t3d.normal());
140 Point3D p3d(pos_i);
141 Point3D nearest_pt = p3d.project(PL);
142 Real r = (nearest_pt.origin - pos_i).norm();
143
144 float d = p3d.distance(PL);
145 d = abs(d);
146 if (smoothingLength - d > EPSILON&& smoothingLength* smoothingLength - d * d > EPSILON&& d > EPSILON)
147 {
148
149 Real a_ij =
150 kernel(r, smoothingLength, scale)
151 * 2.0 * (M_PI) * (1 - d / smoothingLength)
152 * calculateIntersectionArea(p3d, t3d, smoothingLength)
153 / ((M_PI) * (smoothingLength * smoothingLength - d * d));
154 rho_i += mass * a_ij;
155
156 }
157 }
158 //printf("Boundary: %f \n", rho_i);
159 }
160
161 rhoArr[pId] += rho_i;
162 }
163
164 template<typename TDataType>
165 void SemiAnalyticalSummationDensity<TDataType>::compute(
166 DArray<Real>& rho,
167 DArray<Coord>& pos,
168 DArray<TopologyModule::Triangle>& Tri,
169 DArray<Coord>& positionTri,
170 DArrayList<int>& neighbors,
171 DArrayList<int>& neighborsTri,
172 Real smoothingLength,
173 Real mass,
174 Real sampling_distance)
175 {
176 cuZerothOrder(rho.size(), this->varKernelType()->getDataPtr()->currentKey(), this->mScalingFactor,
177 SD_ComputeDensity,
178 rho,
179 pos,
180 neighbors,
181 smoothingLength,
182 mass,
183 sampling_distance);
184
185 if (neighborsTri.size() > 0)
186 {
187 cuIntegral(rho.size(), this->varKernelType()->getDataPtr()->currentKey(), this->mScalingFactor,
188 SD_BoundaryIntegral,
189 rho,
190 pos,
191 Tri,
192 positionTri,
193 neighborsTri,
194 smoothingLength,
195 mass);
196 }
197 }
198
199 template<typename TDataType>
200 void SemiAnalyticalSummationDensity<TDataType>::calculateParticleMass()
201 {
202 Real rho_0 = this->varRestDensity()->getData();
203 Real d = this->inSamplingDistance()->getData();
204
205 m_particle_mass = d*d*d*rho_0;
206 }
207
208 DEFINE_CLASS(SemiAnalyticalSummationDensity);
209}