1#include "NormalForce.h"
6 template<typename TDataType>
7 NormalForce<TDataType>::NormalForce()
10 this->outNormalForce()->allocate();
14 template<typename TDataType>
15 NormalForce<TDataType>::~NormalForce()
17 mNormalForceFlag.clear();
20 template<typename Real, typename Coord>
21 __global__ void NormalForce_UpdateVelocity(
24 DArray<Coord> Velocities,
25 DArray<Coord> positions,
26 DArray<Coord> normals,
31 int pId = threadIdx.x + (blockIdx.x * blockDim.x);
32 if (pId >= forces.size()) return;
36 forces[pId] = Coord(0.0f);
37 Velocities[pId] = Coord(0.0f);
42 forces[pId] = normals[pId] * scale;
44 Velocities[pId] += dt * (forces[pId]);
48 template<typename Coord>
49 Real __device__ PointToEdgeDistance(Coord O, Coord A, Coord B)
53 Coord AP = AB.dot(AO) * AB;
55 return (O - P).norm();
59 template<typename Coord>
60 Real __device__ PointToMeshDistance(Coord O, Coord A, Coord B, Coord C, Coord normal)
65 return AO.dot(normal) / normal.norm();
70 template<typename Coord>
71 __global__ void NormalForce_EmptyEdge(
72 DArray<bool> NormalForceFlag,
73 DArray<Coord> positions,
74 DArrayList<int> triangle_neighbors,
75 DArray<int> particleMeshID,
76 DArray<Coord> vertices,
77 DArray<TopologyModule::Triangle> triangles,
78 DArray<Coord> noramls,
79 DArray<TopologyModule::Edg2Tri> Edg2Tri,
80 DArray<TopologyModule::Tri2Edg> Tri2Edg
82 int pId = threadIdx.x + (blockIdx.x * blockDim.x);
83 if (pId >= positions.size()) return;
85 NormalForceFlag[pId] = true;
87 List<int>& nbrTriIds_i = triangle_neighbors[pId];
88 int nbrSize = nbrTriIds_i.size();
93 int triangleID = particleMeshID[pId];
94 int& A_id = triangles[triangleID][0];
95 int& B_id = triangles[triangleID][1];
96 int& C_id = triangles[triangleID][2];
98 Real d_ab = PointToEdgeDistance(positions[pId], vertices[A_id], vertices[B_id]);
99 Real d_bc = PointToEdgeDistance(positions[pId], vertices[B_id], vertices[C_id]);
100 Real d_ac = PointToEdgeDistance(positions[pId], vertices[A_id], vertices[C_id]);
103 Real distance = PointToMeshDistance(positions[pId],
104 vertices[triangles[triangleID][0]],
105 vertices[triangles[triangleID][1]],
106 vertices[triangles[triangleID][2]],
111 NormalForceFlag[pId] = false;
115 template<typename TDataType>
116 void NormalForce<TDataType>::constrain()
118 //std::cout << "Normal Force!" << std::endl;
119 int num = this->inPosition()->size();
121 if (this->outNormalForce()->isEmpty())
122 this->outNormalForce()->allocate();
124 if (this->outNormalForce()->size() != num)
126 this->outNormalForce()->resize(num);
129 if (mNormalForceFlag.size() != num)
131 mNormalForceFlag.resize(num);
134 auto ts = this->inTriangleSet()->constDataPtr();
135 auto& vertices = ts->getPoints();
136 auto& triangles = ts->getTriangles();
137 auto& edge2tri = ts->getEdge2Triangle();
138 auto& tri2edge = ts->getTriangle2Edge();
140 cuExecute(num, NormalForce_EmptyEdge,
142 this->inPosition()->getData(),
143 this->inTriangleNeighborIds()->getData(),
144 this->inParticleMeshID()->getData(),
147 this->inParticleNormal()->getData(),
152 cuExecute(num, NormalForce_UpdateVelocity,
153 this->outNormalForce()->getData(),
155 this->inVelocity()->getData(),
156 this->inPosition()->getData(),
157 this->inParticleNormal()->getData(),
158 this->inTimeStep()->getValue(),
159 this->varStrength()->getValue()
164 DEFINE_CLASS(NormalForce);