PeriDyno 1.0.0
Loading...
Searching...
No Matches
RigidWaterCoupling.cu
Go to the documentation of this file.
1#include "RigidWaterCoupling.h"
2
3#include "Math/Lerp.h"
4
5#include "Primitive/Primitive3D.h"
6
7namespace dyno
8{
9 template<typename TDataType>
10 RigidWaterCoupling<TDataType>::RigidWaterCoupling()
11 : Node()
12 {
13 }
14
15 template<typename TDataType>
16 RigidWaterCoupling<TDataType>::~RigidWaterCoupling()
17 {
18 }
19
20 template<typename TDataType>
21 void RigidWaterCoupling<TDataType>::resetStates()
22 {
23 }
24
25 template<typename Coord, typename Triangle>
26 __global__ void C_ComputeForceAndTorque(
27 DArray<Coord> force,
28 DArray<Coord> torque,
29 DArray<Coord> vertices,
30 DArray<Triangle> indices,
31 DArray2D<Real> heights,
32 Coord barycenter,
33 Coord gravity,
34 Coord origin,
35 Real spacing,
36 Real rho)
37 {
38 int tId = threadIdx.x + blockIdx.x * blockDim.x;
39 if (tId >= indices.size()) return;
40
41 Triangle index_i = indices[tId];
42
43 Coord v0 = vertices[index_i[0]];
44 Coord v1 = vertices[index_i[1]];
45 Coord v2 = vertices[index_i[2]];
46
47 Triangle3D triangle(v0, v1, v2);
48
49 //Triangle normal
50 Coord normal_i = (v2 - v0).cross(v1 - v0);
51 normal_i.normalize();
52
53 Coord triangle_center = (v0 + v1 + v2) / Real(3);
54
55 //Calculate buoyancy
56 Real sea_level = bilinear(heights, (triangle_center.x - origin.x) / spacing, (triangle_center.z - origin.z) / spacing);
57 Real h = triangle_center.y < sea_level ? (sea_level - triangle_center.y) : Real(0);
58
59 Real pressure = rho * gravity.norm() * h;
60
61 Coord force_i = pressure * triangle.area() * normal_i;
62 Coord torque_i = -force_i.cross(triangle_center - barycenter);
63
64 force[tId] = force_i;
65 torque[tId] = torque_i;
66 }
67
68 template<typename TDataType>
69 void RigidWaterCoupling<TDataType>::updateStates()
70 {
71 Real dt = this->stateTimeStep()->getData();
72
73 auto vessels = this->getVessels();
74 auto ocean = this->getOcean();
75
76 auto patch = ocean->getOceanPatch();
77
78 for (auto mesh : vessels)
79 {
80 auto& triangles = mesh->stateEnvelope()->getData();
81
82 Real mass = mesh->stateMass()->getData();
83 Coord barycenter = mesh->stateBarycenter()->getData();
84 Coord velocity = mesh->stateVelocity()->getData();
85 Coord angular_velocity = mesh->stateAngularVelocity()->getData();
86 Matrix inertia = mesh->stateInertia()->getData();
87
88 Coord gravity = mesh->varGravity()->getData();
89
90 auto& vertices = triangles.getPoints();
91 auto& indices = triangles.getTriangles();
92
93 uint num = indices.size();
94
95 if (mForce.size() != num) {
96 mForce.resize(num);
97 mTorque.resize(num);
98 }
99
100 auto heights = patch->stateHeightField()->getDataPtr();
101 auto& displacements = heights->calculateHeightField();
102 Coord origin = heights->getOrigin();
103 Real h = heights->getGridSpacing();
104
105 cuExecute(num,
106 C_ComputeForceAndTorque,
107 mForce,
108 mTorque,
109 vertices,
110 indices,
111 displacements,
112 barycenter,
113 gravity,
114 origin,
115 h,
116 Real(1000));
117
118 Coord F_total = mReduce.accumulate(mForce.begin(), mForce.size());
119 Coord T_total = mReduce.accumulate(mTorque.begin(), mTorque.size());
120
121 velocity += dt * F_total / mass;
122 angular_velocity += dt * inertia.inverse() * T_total;
123
124 velocity *= this->varDamping()->getValue();
125 angular_velocity *= this->varRotationalDamping()->getValue();
126
127 mesh->stateVelocity()->setValue(velocity);
128 mesh->stateAngularVelocity()->setValue(angular_velocity);
129 }
130 }
131
132 DEFINE_CLASS(RigidWaterCoupling);
133}