PeriDyno 1.0.0
Loading...
Searching...
No Matches
PaticleUniformAnalysis.cu
Go to the documentation of this file.
1#include "PaticleUniformAnalysis.h"
2#include <sstream>
3#include <iostream>
4#include <fstream>
5#include "ParticleSystem/Module/Kernel.h"
6
7
8namespace dyno {
9
10 template<typename TDataType>
11 PaticleUniformAnalysis<TDataType>::PaticleUniformAnalysis()
12 : ConstraintModule()
13 {
14 mSummation = std::make_shared<SummationDensity<TDataType>>();
15 this->inSmoothingLength()->connect(mSummation->inSmoothingLength());
16 this->inSamplingDistance()->connect(mSummation->inSamplingDistance());
17 this->inPosition()->connect(mSummation->inPosition());
18 this->inNeighborIds()->connect(mSummation->inNeighborIds());
19
20 };
21
22 template<typename TDataType>
23 PaticleUniformAnalysis<TDataType>::~PaticleUniformAnalysis() {
24
25 m_SurfaceEnergy.clear();
26 m_DensityEnergy.clear();
27 m_TotalEnergy.clear();
28 m_Count.clear();
29 m_Density.clear();
30 //m_output->close();
31 };
32
33
34 template <typename Real, typename Coord>
35 __global__ void K_SufaceEnergy(
36 DArray<Real> Energy,
37 DArray<Real> density,
38 DArray<Coord> posArr,
39 DArrayList<int> neighbors,
40 Real smoothingLength)
41 {
42 int pId = threadIdx.x + (blockIdx.x * blockDim.x);
43 if (pId >= posArr.size()) return;
44
45 SmoothKernel<Real> kern;
46 Coord pos_i = posArr[pId];
47
48 List<int>& list_i = neighbors[pId];
49 int nbSize = list_i.size();
50 Coord g(0.0f);
51 Real w(0.0f);
52 for (int ne = 0; ne < nbSize; ne++)
53 {
54 int j = list_i[ne];
55 Real r = (pos_i - posArr[j]).norm();
56
57 if (r > EPSILON)
58 {
59 g += kern.gradient(r, smoothingLength, 1.0) * (pos_i - posArr[j]) * (1.0f / r);
60 w += kern.Weight(r, smoothingLength);
61 }
62 }
63 if (w < EPSILON) w = EPSILON;
64
65 g = g / w;
66
67 Energy[pId] = g.dot(g);
68 }
69
70
71
72 template <typename Real>
73 __global__ void K_DensityEnergy(
74 DArray<Real> Energy,
75 DArray<Real> density,
76 Real rho_0
77 )
78 {
79 int pId = threadIdx.x + (blockIdx.x * blockDim.x);
80 if (pId >= Energy.size()) return;
81 Real e = density[pId] < rho_0 ? rho_0 - density[pId] : 0.0f;
82 Energy[pId] = e * e / (rho_0 * rho_0);
83
84 //printf("%f\r\n", Energy[pId]);
85 }
86
87
88 template <typename Real>
89 __global__ void K_TotalEnergy(
90 DArray<Real> TotalEnergy,
91 DArray<Real> DensityEnergy,
92 DArray<Real> SurfaceEnergy,
93 Real A_d,
94 Real A_s
95 )
96 {
97 int pId = threadIdx.x + (blockIdx.x * blockDim.x);
98 if (pId >= TotalEnergy.size()) return;
99
100 TotalEnergy[pId] = A_d* DensityEnergy[pId] + A_s * SurfaceEnergy[pId];
101 //if(TotalEnergy[pId] > 1.0)
102 //printf("%f, %f + %f \r\n", TotalEnergy[pId], DensityEnergy[pId], SurfaceEnergy[pId]);
103 }
104
105
106
107
108 template<typename TDataType>
109 void PaticleUniformAnalysis<TDataType>::constrain() {
110
111 if (initial)
112 {
113 this->initializeImpl();
114 initial = false;
115
116 }
117
118 int num = this->inPosition()->getData().size();
119
120 if (m_TotalEnergy.size() != num)
121 {
122 m_DensityEnergy.resize(num);
123 m_SurfaceEnergy.resize(num);
124 m_TotalEnergy.resize(num);
125 m_Count.resize(num);
126 m_reduce = Reduction<float>::Create(num);
127 m_arithmetic = Arithmetic<float>::Create(num);
128 m_reduce_real = Reduction<float>::Create(num);
129 m_Density.resize(num);
130
131 }
132
133 mSummation->varRestDensity()->setValue(1000.0f);
134 mSummation->varKernelType()->setCurrentKey(0);
135 mSummation->update();
136
137
138 std::cout << "m_init_density: " << m_init_density << std::endl;
139
140 cuExecute(num, K_DensityEnergy,
141 m_DensityEnergy,
142 mSummation->outDensity()->getData(),
143 m_init_density
144 )
145
146
147 cuExecute(num, K_SufaceEnergy,
148 m_SurfaceEnergy,
149 mSummation->outDensity()->getData(),
150 this->inPosition()->getData(),
151 this->inNeighborIds()->getData(),
152 0.0125f);
153
154 cuExecute(num, K_TotalEnergy,
155 m_TotalEnergy,
156 m_DensityEnergy,
157 m_SurfaceEnergy,
158 1.0f,
159 0.8f
160 )
161
162 Real total_energy = m_arithmetic->Dot(m_TotalEnergy, m_TotalEnergy);
163 Real total_Surface_Energy = m_arithmetic->Dot(m_SurfaceEnergy, m_SurfaceEnergy);
164
165 //std::cout << "*** PaticleUniformAnalysis :" << sqrt(total_energy)/num << std::endl;
166 std::cout << "*** total_energy: " << total_energy/num <<", Surface_Energy: "<< total_Surface_Energy/num<< std::endl;
167 if (counter % 1 == 0)
168 {
169 *m_output << total_energy / num << std::endl;
170 }
171 counter++;
172
173
174
175
176 };
177
178
179
180 template<typename TDataType>
181 bool PaticleUniformAnalysis<TDataType>::initializeImpl() {
182 std::cout << "PaticleUniformAnalysis initializeImpl " << std::endl;
183
184 std::string filename = mOutpuPath + mOutputPrefix + std::string(".txt");
185
186 m_output.reset(new std::fstream(filename.c_str(), std::ios::out));
187
188 int num = this->inPosition()->getData().size();
189
190 if (m_TotalEnergy.size() != num)
191 {
192 m_DensityEnergy.resize(num);
193 m_SurfaceEnergy.resize(num);
194 m_TotalEnergy.resize(num);
195 m_Count.resize(num);
196 m_reduce = Reduction<float>::Create(num);
197 m_arithmetic = Arithmetic<float>::Create(num);
198 m_reduce_real = Reduction<float>::Create(num);
199 m_Density.resize(num);
200
201 }
202
203
204 mSummation->varRestDensity()->setValue(1000.0f);
205 mSummation->varKernelType()->setCurrentKey(0);
206 mSummation->update();
207
208 m_init_density = m_reduce_real->maximum(
209 mSummation->outDensity()->getData().begin(),
210 mSummation->outDensity()->getData().size());
211
212 return true;
213 };
214
215
216
217 template<typename TDataType>
218 void PaticleUniformAnalysis<TDataType>::setNamePrefix(std::string prefix)
219 {
220 mOutputPrefix = prefix;
221 }
222
223 template<typename TDataType>
224 void PaticleUniformAnalysis<TDataType>::setOutputPath(std::string path)
225 {
226 mOutpuPath = path;
227 }
228
229
230
231 DEFINE_CLASS(PaticleUniformAnalysis);
232}