5#include "Algorithm/CudaRand.h"
9 IMPLEMENT_TCLASS(Wake, TDataType)
11 template<typename TDataType>
12 Wake<TDataType>::Wake()
13 : CapillaryWave<TDataType>()
15 this->setAutoHidden(true);
18 template<typename TDataType>
19 Wake<TDataType>::~Wake()
23 template <typename Real, typename Coord2D, typename Coord3D, typename Coord4D, typename TriangleIndex>
24 __global__ void W_AccumlateTrails(
25 DArray2D<Coord2D> sources,
26 DArray2D<Real> weights,
27 DArray2D<Coord4D> grid,
28 DArray<Coord3D> vertices,
29 DArray<TriangleIndex> indices,
32 Coord3D vesselVelocity,
33 Coord3D vesselAngularVelocity,
36 int tId = threadIdx.x + blockIdx.x * blockDim.x;
37 if (tId >= indices.size()) return;
39 TriangleIndex index_i = indices[tId];
41 Coord3D v0 = vertices[index_i[0]];
42 Coord3D v1 = vertices[index_i[1]];
43 Coord3D v2 = vertices[index_i[2]];
45 Coord3D tc = (v0 + v1 + v2) / Real(3);
50 Real x = (tc.x - waveOrigin.x) / spacing;
51 Real y = (tc.z - waveOrigin.z) / spacing;
53 Coord3D vel = vesselVelocity + (tc - vesselCenter).cross(vesselAngularVelocity);
55 Coord4D g_i = bilinear(grid, x, y, LerpMode::CLAMP_TO_BORDER);
57 //If the center is above the water surface, no impulse will be imposed
58 Real d = (g_i.x - tc.y);
70 i0 = i0 < 1 ? 1 : (i0 >= nx - 2 ? nx - 2 : i0);
71 j0 = j0 < 1 ? 1 : (j0 >= ny - 2 ? ny - 2 : j0);
73 i1 = i1 < 1 ? 1 : (i1 >= nx - 2 ? nx - 2 : i1);
74 j1 = j1 < 1 ? 1 : (j1 >= ny - 2 ? ny - 2 : j1);
79 const float w00 = (1.0f - fx) * (1.0f - fy);
80 const float w10 = fx * (1.0f - fy);
81 const float w01 = (1.0f - fx) * fy;
82 const float w11 = fx * fy;
84 atomicAdd(&sources(i0, j0).x, w00 * hu);
85 atomicAdd(&sources(i0, j0).y, w00 * hv);
86 atomicAdd(&weights(i0, j0), w00);
88 atomicAdd(&sources(i0, j1).x, w01 * hu);
89 atomicAdd(&sources(i0, j1).y, w01 * hv);
90 atomicAdd(&weights(i0, j1), w01);
92 atomicAdd(&sources(i1, j0).x, w10 * hu);
93 atomicAdd(&sources(i1, j0).y, w10 * hv);
94 atomicAdd(&weights(i1, j0), w10);
96 atomicAdd(&sources(i1, j1).x, w11 * hu);
97 atomicAdd(&sources(i1, j1).y, w11 * hv);
98 atomicAdd(&weights(i1, j1), w11);
101 template <typename Real, typename Coord2D, typename Coord4D>
102 __global__ void W_AddTrails(
103 DArray2D<Coord2D> sources,
104 DArray2D<Real> weights,
105 DArray2D<Coord4D> grid,
108 int i = threadIdx.x + blockIdx.x * blockDim.x;
109 int j = threadIdx.y + blockIdx.y * blockDim.y;
111 if (i < grid.nx() && j < grid.ny())
113 //if (weights(i, j) > 1)
115 RandNumber gen(i * j);
117 auto rnd = gen.Generate();
119 Coord4D gij = grid(i, j);
120 Coord2D sij = weights(i, j) > 1 ? sources(i, j) / weights(i, j) : sources(i, j);
122 gij.y += mag * rnd * sij.x;
123 gij.z += mag * rnd * sij.y;
130 template<typename TDataType>
131 void Wake<TDataType>::addTrails()
133 uint res = this->varResolution()->getValue();
135 Real dt = this->stateTimeStep()->getValue();
137 auto heights = this->stateHeightField()->getDataPtr();
138 auto& displacements = heights->getDisplacement();
139 auto waveOrigin = heights->getOrigin();
140 auto h = heights->getGridSpacing();
143 auto vessel = this->getVessel();
144 auto& triangles = vessel->stateEnvelope()->getData();
146 auto vesselCenter = vessel->stateCenter()->getData();
147 auto vesselVelocity = vessel->stateVelocity()->getData();
148 auto avesselAngularVelocity = vessel->stateAngularVelocity()->getData();
150 auto& vertices = triangles.getPoints();
151 auto& indices = triangles.getTriangles();
153 uint num = indices.size();
155 if (this->mDeviceGrid.nx() != mWeight.nx() || this->mDeviceGrid.ny() != mWeight.ny())
157 mWeight.resize(this->mDeviceGrid.nx(), this->mDeviceGrid.ny());
158 mSource.resize(this->mDeviceGrid.nx(), this->mDeviceGrid.ny());
174 avesselAngularVelocity,
177 Real mag = this->varMagnitude()->getValue();
179 cuExecute2D(make_uint2(this->mDeviceGrid.nx(), this->mDeviceGrid.ny()),
186 this->mDeviceGridNext.assign(this->mDeviceGrid);
190 template<typename TDataType>
191 void Wake<TDataType>::updateStates()
193 if (this->getVessel() != nullptr)
196 CapillaryWave<TDataType>::updateStates();