PeriDyno 1.0.0
Loading...
Searching...
No Matches
CodimensionalPD.cu
Go to the documentation of this file.
1#pragma once
2#include "CodimensionalPD.h"
3#include "ParticleSystem/Module/ParticleIntegrator.h"
4#include "Primitive/Primitive3D.h"
5#include "Topology/TriangleSet.h"
6#include "Mapping/PointSetToPointSet.h"
7
8#include "Module/CoSemiImplicitHyperelasticitySolver.h"
9
10namespace dyno
11{
12 IMPLEMENT_TCLASS(CodimensionalPD, TDataType)
13
14 template<typename TDataType>
15 CodimensionalPD<TDataType>::CodimensionalPD()
16 : TriangularSystem<TDataType>()
17 {
18 this->varHorizon()->setValue(0.0085);
19
20 auto integrator = std::make_shared<ParticleIntegrator<TDataType>>();
21 this->stateTimeStep()->connect(integrator->inTimeStep());
22 this->statePosition()->connect(integrator->inPosition());
23 this->stateVelocity()->connect(integrator->inVelocity());
24 this->stateAttribute()->connect(integrator->inAttribute());
25 this->animationPipeline()->pushModule(integrator);
26
27 auto hyperElasticity = std::make_shared<CoSemiImplicitHyperelasticitySolver<TDataType>>();
28 this->varHorizon()->connect(hyperElasticity->inHorizon());
29 this->stateTimeStep()->connect(hyperElasticity->inTimeStep());
30 this->varEnergyType()->connect(hyperElasticity->inEnergyType());
31 this->varEnergyModel()->connect(hyperElasticity->inEnergyModels());
32 this->stateRestPosition()->connect(hyperElasticity->inX());
33 this->statePosition()->connect(hyperElasticity->inY());
34 this->stateVelocity()->connect(hyperElasticity->inVelocity());
35 this->stateRestNorm()->connect(hyperElasticity->inRestNorm());
36 this->stateNorm()->connect(hyperElasticity->inNorm());
37 this->stateRestShape()->connect(hyperElasticity->inBonds());
38 this->stateAttribute()->connect(hyperElasticity->inAttribute());
39 this->stateMaxLength()->connect(hyperElasticity->inUnit());
40 this->stateOldPosition()->connect(hyperElasticity->inOldPosition());
41 this->stateTriangleSet()->connect(hyperElasticity->inTriangularMesh());
42
43 this->animationPipeline()->pushModule(hyperElasticity);
44
45 EnergyModels<Real> funcs;
46 Real s0 = hyperElasticity->getS0(2000,0.1);
47 Real s1 = hyperElasticity->getS1(2000,0.1);
48 funcs.linearModel = LinearModel<Real>(48000, 12000);
49 funcs.neohookeanModel = NeoHookeanModel<Real>(s0,s1);
50 funcs.stvkModel = StVKModel<Real>(1, 12000);
51 funcs.xuModel = XuModel<Real>(hyperElasticity->getE());
52 funcs.fiberModel = FiberModel<Real>(1, 1, 1);
53
54 this->varEnergyModel()->setValue(funcs);
55
56 this->setDt(0.001f);
57 }
58
59 template<typename TDataType>
60 CodimensionalPD<TDataType>::~CodimensionalPD()
61 {
62
63 }
64
65
66
67 template<typename TDataType>
68 void CodimensionalPD<TDataType>::updateTopology()
69 {
70 auto triSet = TypeInfo::cast<TriangleSet<TDataType>>(this->stateTriangleSet()->getDataPtr());
71 triSet->getPoints().assign(this->statePosition()->getData());
72 triSet->updateAngleWeightedVertexNormal(this->stateNorm()->getData());
73 }
74
75
76 template<typename TDataType>
77 void CodimensionalPD<TDataType>::loadSurface(std::string filename)
78 {
79 auto triSetPtr = TypeInfo::cast<TriangleSet<TDataType>>(this->stateTriangleSet()->getDataPtr());
80 triSetPtr ->loadObjFile(filename);
81 triSetPtr ->update();
82 }
83
84
85 template<typename TDataType>
86 void CodimensionalPD<TDataType>::setEnergyModel(XuModel<Real> model)
87 {
88 this->varEnergyType()->setValue(Xuetal);
89
90 auto models = this->varEnergyModel()->getValue();
91 models.xuModel = model;
92
93 this->varEnergyModel()->setValue(models);
94 }
95
96 template<typename TDataType>
97 void CodimensionalPD<TDataType>::setEnergyModel(NeoHookeanModel<Real> model)
98 {
99 this->varEnergyType()->setValue(NeoHooekean);
100
101 auto models = this->varEnergyModel()->getValue();
102 models.neohookeanModel = model;
103
104 this->varEnergyModel()->setValue(models);
105 }
106
107 template<typename TDataType>
108 void CodimensionalPD<TDataType>::setEnergyModel(LinearModel<Real> model)
109 {
110 this->varEnergyType()->setValue(Linear);
111
112 auto models = this->varEnergyModel()->getValue();
113 models.linearModel = model;
114
115 this->varEnergyModel()->setValue(models);
116 }
117
118 template<typename TDataType>
119 void CodimensionalPD<TDataType>::setEnergyModel(StVKModel<Real> model)
120 {
121 this->varEnergyType()->setValue(StVK);
122
123 auto models = this->varEnergyModel()->getValue();
124 models.stvkModel = model;
125
126 this->varEnergyModel()->setValue(models);
127 }
128
129 template<typename TDataType>
130 void CodimensionalPD<TDataType>::setEnergyModel(FiberModel<Real> model)
131 {
132 this->varEnergyType()->setValue(Fiber);
133
134 auto models = this->varEnergyModel()->getValue();
135 models.fiberModel = model;
136
137 this->varEnergyModel()->setValue(models);
138 }
139
140 template<typename TDataType>
141 bool CodimensionalPD<TDataType>::translate(Coord t)
142 {
143 auto triSet = TypeInfo::cast<TriangleSet<TDataType>>(this->stateTriangleSet()->getDataPtr());
144 triSet->translate(t);
145
146 return true;
147 }
148
149 template<typename TDataType>
150 bool CodimensionalPD<TDataType>::scale(Real s)
151 {
152 auto triSet = TypeInfo::cast<TriangleSet<TDataType>>(this->stateTriangleSet()->getDataPtr());
153 triSet->scale(s);
154
155 this->varHorizon()->setValue(s * this->varHorizon()->getData());
156
157 return true;
158 }
159
160 template<typename TDataType>
161 bool CodimensionalPD<TDataType>::scale(Coord s)
162 {
163 auto triSet = TypeInfo::cast<TriangleSet<TDataType>>(this->stateTriangleSet()->getDataPtr());
164 triSet->scale(s);
165
166 this->varHorizon()->setValue((s[0] + s[1] + s[2]) / 3.0f * this->varHorizon()->getData());
167
168 return true;
169 }
170
171 template<typename TDataType>
172 void CodimensionalPD<TDataType>::preUpdateStates()
173 {
174
175 auto& posOld = this->stateOldPosition()->getData();
176 auto& posNew = this->statePosition()->getData();
177 posOld.assign(posNew);
178
179 }
180
181 template<typename Matrix>
182 __global__ void InitRotation(
183 DArray<Matrix> rots)
184 {
185 int pId = threadIdx.x + (blockIdx.x * blockDim.x);
186 if (pId >= rots.size()) return;
187
188 rots[pId] = Matrix::identityMatrix();
189 }
190
191 template<typename TDataType>
192 void CodimensionalPD<TDataType>::resetStates()
193 {
194 TriangularSystem<TDataType>::resetStates();
195
196 printf("inside reset States\n");
197 auto triSet = TypeInfo::cast<TriangleSet<TDataType>>(this->stateTriangleSet()->getDataPtr());
198 if (triSet == nullptr) return;
199 printf("host attribute\n");
200
201 CArray<Attribute> host_attribute;
202 host_attribute.resize(triSet->getPoints().size());
203 for (int i = 0; i < triSet->getPoints().size(); i++)
204 {
205 host_attribute[i] = Attribute();
206 }
207
208 CArray<Coord> triPoints;
209 CArray<TopologyModule::Triangle> triIds;
210
211 triPoints.resize(triSet->getPoints().size());
212 triPoints.assign(triSet->getPoints());
213
214 triIds.resize(triSet->getTriangles().size());
215 triIds.assign(triSet->getTriangles());
216
217
218 float global_min = 1000000;
219 float global_max = 0.0f;
220 for (int i = 0; i < triIds.size(); i++)
221 {
222 auto tri = triIds[i];
223
224 Vec3f v0 = triPoints[tri[0]];
225 Vec3f v1 = triPoints[tri[1]];
226 Vec3f v2 = triPoints[tri[2]];
227
228
229 Vec3f min_v = v0.minimum(v1).minimum(v2);
230 Vec3f max_v = v0.maximum(v1).maximum(v2);
231
232 Vec3f bounding = max_v - min_v;
233
234 float max_edge = maximum(maximum(bounding[0], bounding[1]), bounding[2]);
235
236 global_min = max_edge < global_min ? max_edge : global_min;
237 global_max = max_edge > global_max ? max_edge : global_max;
238 }
239
240
241
242 this->varHorizon()->setValue(1.5 * global_max);
243
244 printf("host attr size %d\n", host_attribute.size());
245
246 int vNum = triSet->getPoints().size();
247
248
249 this->stateRestNorm()->resize(vNum);
250 triSet->updateAngleWeightedVertexNormal(this->stateRestNorm()->getData());
251
252
253 this->stateNorm()->assign(this->stateRestNorm()->getData());
254
255
256 this->stateRestPosition()->assign(triSet->getPoints());
257
258 this->stateOldPosition()->assign(triSet->getPoints());
259
260 this->stateAttribute()->assign(host_attribute);
261
262 host_attribute.clear();
263
264 triIds.clear();
265 triPoints.clear();
266
267 this->updateVolume();
268 this->updateRestShape();
269 }
270
271
272 __global__ void CPD_SetSize(
273 DArray<uint> index,
274 DArrayList<int> lists)
275 {
276 int pId = threadIdx.x + (blockIdx.x * blockDim.x);
277 if (pId >= lists.size()) return;
278 index[pId] = lists[pId].size() + 1;
279 }
280
281
282 template<typename Coord, typename Bond>
283 __global__ void SetRestShape(
284 DArray<Coord> restPos,
285 DArrayList<Bond> restShapes,
286 DArrayList<int> lists)
287 {
288 int pId = threadIdx.x + (blockIdx.x * blockDim.x);
289 if (pId >= lists.size()) return;
290
291
292 List<Bond>& list_i = restShapes[pId];
293
294 List<int> list = lists[pId];
295
296 list_i.insert(Bond(pId, restPos[pId]));
297
298 for (auto it = list.begin(); it != list.end(); it++)
299 {
300 int j = *it;
301
302 list_i.insert(Bond(j, restPos[j]));
303 }
304
305
306 int size_i = restShapes[pId].size();
307 }
308
309 template<typename TDataType>
310 void CodimensionalPD<TDataType>::updateRestShape()
311 {
312 auto triSet = TypeInfo::cast<TriangleSet<TDataType>>(this->stateTriangleSet()->getDataPtr());
313 if (triSet == nullptr) return;
314
315 DArrayList<int> neighbors;
316 triSet->requestPointNeighbors(neighbors);
317
318 auto& restPos = this->stateRestPosition()->getData();
319
320 this->stateRestShape()->resize(restPos.size());
321
322 auto index = this->stateRestShape()->getData().index();
323 auto elements = this->stateRestShape()->getData().elements();
324
325 DArray<uint> index_temp;
326 index_temp.resize(index.size());
327
328 cuExecute(neighbors.size(),
329 CPD_SetSize,
330 index_temp,
331 neighbors);
332
333 this->stateRestShape()->getData().resize(index_temp);
334
335 cuExecute(neighbors.size(),
336 SetRestShape,
337 restPos,
338 stateRestShape()->getData(),
339 neighbors);
340
341 neighbors.clear();
342 }
343
344 template<typename Real, typename Coord, typename Triangle>
345 __global__ void HB_UpdateUnit(
346 DArray<Coord> restPos,
347 DArray<Triangle> tris,
348 DArray<Real> Min,
349 DArray<Real> Max) {
350
351 int tId = threadIdx.x + (blockIdx.x * blockDim.x);
352 if (tId >= tris.size()) return;
353
354 auto Coordnorm = [](Coord res) {
355 Real c = Real(0);
356 Real tmp = res[0] * res[0] + res[1] * res[1] + res[2] * res[2];
357 c = sqrt(tmp);
358 return c;
359 };
360
361 Triangle triIndex = tris[tId];
362 Real length1 = Coordnorm(restPos[triIndex[0]] - restPos[triIndex[1]]);
363 Real length2 = Coordnorm(restPos[triIndex[1]] - restPos[triIndex[2]]);
364 Real length3 = Coordnorm(restPos[triIndex[2]] - restPos[triIndex[0]]);
365 auto tmpMax = maximum(maximum(length3, Real(1e-9)), maximum(length1, length2));
366 auto tmpMin = minimum(maximum(length3, Real(1e-9)), minimum(length1, length2));
367 Min[tId] = tmpMin;
368 Max[tId] = tmpMax;
369 }
370
371 template<typename Real, typename Coord, typename Triangle>
372 __global__ void HB_CalculateVolume(
373 DArray<Real> volume,
374 DArray<Coord> restPos,
375 DArray<Triangle> tris,
376 DArrayList<int> lists)
377 {
378 int pId = threadIdx.x + (blockIdx.x * blockDim.x);
379 if (pId >= volume.size()) return;
380
381 Real vol_i = Real(0);
382
383 List<int>& list_i = lists[pId];
384 int nbSize = list_i.size();
385
386 for (int i = 0; i < nbSize; i++)
387 {
388 int triId = list_i[i];//lists.getElement(pId, i);
389 Triangle triIndex = tris[triId];
390
391 TTriangle3D<Real> tri(restPos[triIndex[0]], restPos[triIndex[1]], restPos[triIndex[2]]);
392
393 vol_i += abs(tri.area());
394 }
395
396 //volume[pId] = samplingDistance * samplingDistance * samplingDistance;//1.0f;//maximum(vol_i, Real(0.0000000000001));
397 volume[pId] = maximum(vol_i, Real(0.0000000000001));
398
399 }
400
401 template<typename TDataType>
402 void CodimensionalPD<TDataType>::updateVolume()
403 {
404 auto triSet = TypeInfo::cast<TriangleSet<TDataType>>(this->stateTriangleSet()->getDataPtr());
405 if (triSet == nullptr) return;
406
407 auto& ver2Tri = triSet->getVertex2Triangles();
408
409 auto& restPos = this->stateRestPosition()->getData();
410
411// if (this->stateMaxLength()->isEmpty()) {
412// this->stateMaxLength()->allocate();
413// }
414// if (this->stateMinLength()->isEmpty()) {
415// this->stateMinLength()->allocate();
416// }
417
418 DArray<Real> maxL;
419 maxL.resize(triSet->getTriangles().size());
420 DArray<Real> minL;
421 minL.resize(triSet->getTriangles().size());
422
423 cuExecute(triSet->getTriangles().size(),
424 HB_UpdateUnit,
425 restPos,
426 triSet->getTriangles(),
427 minL,
428 maxL
429 );
430
431 this->stateVolume()->resize(restPos.size());
432
433 cuExecute(restPos.size(),
434 HB_CalculateVolume,
435 this->stateVolume()->getData(),
436 restPos,
437 triSet->getTriangles(),
438 ver2Tri);
439
440 auto& volume = this->stateVolume()->getData();
441
442 Reduction<Real> reduce;
443 Real max_vol = reduce.maximum(volume.begin(), volume.size());
444 Real min_vol = reduce.minimum(volume.begin(), volume.size());
445 Real min_L = reduce.minimum(minL.begin(), minL.size());
446 Real max_L = reduce.maximum(maxL.begin(), maxL.size());
447 this->stateMaxLength()->setValue(max_L);
448 this->stateMinLength()->setValue(min_L);
449 printf("max vol: %f; min vol: %f \n", max_vol, min_vol);
450 printf("max length: %f; min length: %f \n",this->stateMaxLength()->getData() , this->stateMinLength()->getData());
451 }
452
453 DEFINE_CLASS(CodimensionalPD);
454}