PeriDyno 1.0.0
Loading...
Searching...
No Matches
TriangularMeshConstraint.cu
Go to the documentation of this file.
1#include "TriangularMeshConstraint.h"
2
3#include "Primitive/Primitive3D.h"
4#include "Primitive/PrimitiveSweep3D.h"
5
6namespace dyno
7{
8 IMPLEMENT_TCLASS(TriangularMeshConstraint, TDataType)
9
10 template<typename TDataType>
11 TriangularMeshConstraint<TDataType>::TriangularMeshConstraint()
12 : ConstraintModule()
13 {
14 }
15
16 template<typename TDataType>
17 TriangularMeshConstraint<TDataType>::~TriangularMeshConstraint()
18 {
19 mPosBuffer.clear();
20
21 mPreviousPosition.clear();
22 mPrivousVertex.clear();
23 }
24
25 template<typename Real, typename Coord>
26 __global__ void TMC_MeshConstrain(
27 DArray<Coord> particle_position,
28 DArray<Coord> particle_velocity,
29 DArray<Coord> particle_position_previous,
30 DArray<Coord> triangle_vertex,
31 DArray<Coord> triangle_vertex_previous,
32 DArray<TopologyModule::Triangle> triangle_index,
33 DArrayList<int> triangle_neighbors,
34 Real friction_normal,
35 Real friction_tangent,
36 Real thickness, //thickness of the boundary
37 Real dt)
38 {
39 typedef typename ::dyno::TPoint3D<Real> Point3D;
40 typedef typename ::dyno::TTriangle3D<Real> Triangle3D;
41 typedef typename ::dyno::TPointSweep3D<Real> PointSweep3D;
42
43 int pId = threadIdx.x + (blockIdx.x * blockDim.x);
44 if (pId >= particle_position.size()) return;
45
46 List<int>& nbrTriIds_i = triangle_neighbors[pId];
47 int nbrSize = nbrTriIds_i.size();
48
49 Coord pos_i = particle_position[pId];
50 Coord pos_i_old = particle_position_previous[pId];
51 Coord vel_i = particle_velocity[pId];
52
53 Point3D point_start(pos_i_old);
54 Point3D point_end(pos_i);
55 PointSweep3D ptSweep(point_start, point_end);
56
57 //Intersection number
58 int num = 0;
59
60 Coord weighted_pos(0);
61 Coord weighted_normal(0);
62
63
64 for (int ne = 0; ne < nbrSize; ne++)
65 {
66 int j = nbrTriIds_i[ne];
67
68 Triangle3D triangle_start(triangle_vertex_previous[triangle_index[j][0]], triangle_vertex_previous[triangle_index[j][1]], triangle_vertex_previous[triangle_index[j][2]]);
69 Triangle3D triangle_end(triangle_vertex[triangle_index[j][0]], triangle_vertex[triangle_index[j][1]], triangle_vertex[triangle_index[j][2]]);
70
71 TriangleSweep3D triSweep(triangle_start, triangle_end);
72
73 //TODO: implement CCD
74// Real t;
75// typename Triangle3D::Param baryc;
76// bool intersected = ptSweep.intersect(triSweep, baryc, t);
77// if (intersected) {
78// //If the particle intersects a triangle according to CCD, move its position back to the middle point
79// point_end = ptSweep.interpolate(t / 2);
80// }
81
82 TPoint3D<Real> proj_end = point_end.project(triangle_end);
83
84 Real dist_end = (proj_end.origin - point_end.origin).norm();
85
86 if (dist_end <= thickness)
87 {
88 Coord dir_j = point_end.origin - proj_end.origin;
89
90 if (dir_j.norm() > REAL_EPSILON) {
91 dir_j.normalize();
92 }
93
94 Coord newpos = proj_end.origin + dir_j * thickness;
95
96 weighted_normal += dir_j;
97 weighted_pos += newpos;
98
99 num++;
100 }
101 }
102
103 if (num > 0)
104 {
105 //Calculate a weighted displacement
106 weighted_pos /= num;
107 weighted_normal /= num;
108
109 particle_position[pId] = weighted_pos;
110
111 vel_i += (weighted_pos - pos_i) / dt;
112
113 Real vel_mag_i = vel_i.dot(weighted_normal);
114 Coord vel_norm_i = vel_mag_i * weighted_normal;
115 Coord vel_tan_i = vel_i - vel_norm_i;
116 vel_norm_i *= (1.0f - friction_normal);
117 vel_tan_i *= (1.0f - friction_tangent);
118
119 particle_velocity[pId] = vel_norm_i + vel_tan_i;
120 }
121 }
122
123 template<typename TDataType>
124 void TriangularMeshConstraint<TDataType>::constrain()
125 {
126 Real thickness = this->varThickness()->getValue();
127
128 Real dt = this->inTimeStep()->getValue();
129
130 auto& positions = this->inPosition()->getData();
131 auto& velocities = this->inVelocity()->getData();
132
133 auto ts = this->inTriangleSet()->constDataPtr();
134
135 auto& vertices = ts->getPoints();
136 auto& triangles = ts->getTriangles();
137
138 auto& neighborIds = this->inTriangleNeighborIds()->getData();
139
140 int p_num = positions.size();
141 if (p_num == 0) return;
142
143 if (positions.size() != mPosBuffer.size()) {
144 mPosBuffer.resize(p_num);
145 mPreviousPosition.assign(positions);
146 }
147
148 mPrivousVertex.assign(vertices);
149
150 if (neighborIds.size() > 0) {
151 cuExecute(p_num,
152 TMC_MeshConstrain,
153 positions,
154 velocities,
155 mPreviousPosition,
156 vertices,
157 mPrivousVertex,
158 triangles,
159 neighborIds,
160 this->varNormalFriction()->getValue(),
161 this->varTangentialFriction()->getValue(),
162 thickness,
163 dt);
164 }
165
166 mPrivousVertex.assign(vertices);
167 mPreviousPosition.assign(positions);
168 }
169
170 DEFINE_CLASS(TriangularMeshConstraint);
171}