-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathkernelFunctions.pde
121 lines (108 loc) · 4 KB
/
kernelFunctions.pde
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
/**
* A "spiky" kernel function used for pressure and density
* @param dist the distance between the two particles
* @param r the smoothing radius
* @return how much the other particle affects the property
*/
float spikyKernelFunction(float dist, float r) {
if (dist > r) return 0;
return (3) / (2 * PI * pow(r, 4)) * pow(r - dist, 2);
}
Cache<Float, Float> gradSpikyCoefficient = new Cache<Float, Float>(
(Function<Float, Float>) (Float r)->2 * PI * pow(r, 4),
smoothingRadius
);
/**
* The gradient of the above spiky kernel function
* @param i the current position
* @param j the other particle's position
* @param r the smoothing radius
* @return the gradient vector
*/
PVector gradSpiky(PVector i, PVector j, float r) {
float dist = PVector.dist(i, j);
if (dist > r) return new PVector();
float coefficient =
-(6 * (r - dist)) / (gradSpikyCoefficient.get(r) * dist);
// return new PVector(
// -(9 * (i.x - j.x) * pow(r - dist, 2)) / (2 * PI * pow(r, 5) * dist),
// -(9 * (i.y - j.y) * pow(r - dist, 2)) / (2 * PI * pow(r, 5) * dist)
// );
return PVector.sub(i, j).mult(coefficient);
}
/**
* A cubic kernel function used to remove particle clumping
* @param dist the distance between the two particles
* @param r the smoothing radius
* @return how much the other particle affects the property
*/
float cubicKernelFunction(float dist, float r) {
if (dist > r) return 0;
return (3) / (2 * PI * pow(r, 5)) * pow(r - dist, 3);
}
Cache<Float, Float> gradCubicCoefficient = new Cache<Float, Float>(
(Function<Float, Float>) (Float r)->2 * PI * pow(r, 5),
smoothingRadius
);
/**
* The gradient of the above cubic kernel function
* @param i the current position
* @param j the other particle's position
* @param r the smoothing radius
* @return the gradient vector
*/
PVector gradCubic(PVector i, PVector j, float r) {
float dist = PVector.dist(i, j);
if (dist > r) return new PVector();
float coefficient =
-(9 * pow(r - dist, 2)) / (gradSpikyCoefficient.get(r) * dist);
// return new PVector(
// -(9 * (i.x - j.x) * pow(r - dist, 2)) / (2 * PI * pow(r, 5) * dist),
// -(9 * (i.y - j.y) * pow(r - dist, 2)) / (2 * PI * pow(r, 5) * dist)
// );
return PVector.sub(i, j).mult(coefficient);
}
Cache<Float, Float> smoothKernelCoefficient = new Cache<Float, Float>(
(Function<Float, Float>) (Float r)->3 / (2 * PI * pow(r, 8)),
smoothingRadius
);
/**
* A smooth kernel function used for everything else
* @param distSq the distance between the two particles, squared. This is
* calculated in the distance calculation anyway, so it is a small optimization
* @param r the smoothing radius
* @return how much the other particle affects the property
*/
float smoothKernelFunction(float distSq, float r) {
// return 128 * (315) / (64 * PI * pow(r, 8)) * pow(pow(r, 2) - distSq,
// 3);
if (distSq > pow(r, 2)) return 0;
// return 3 / (2 * PI * pow(r, 8)) * pow(pow(r, 2) - distSq, 3);
return smoothKernelCoefficient.get(r) * pow(pow(r, 2) - distSq, 3);
}
/**
* A kernel function used for viscosity
* @param dist the distance between the two particles, squared
* @param r the smoothing radius
* @return how much the other particle affects the property
*/
float viscosityKernelFunction(float dist, float r) {
if (dist > r) return 0;
return 15 / (2 * PI * pow(r, 2)) *
(-pow(dist, 3) / (2 * pow(r, 2)) + pow(dist, 2) / pow(r, 2) +
r / (2 * dist) - 2);
}
Cache<Float, Float> laplacianViscosityCoefficient = new Cache<Float, Float>(
(Function<Float, Float>) (Float r)->(30) / (PI * pow(r, 6)),
smoothingRadius
);
/**
* The Laplacian of the above function
* @param dist the distance between the two particles
* @param r the smoothing radius
* @return The laplacian of the viscosity kernel
*/
float laplacianViscosity(float dist, float r) {
if (dist > r) return 0;
return laplacianViscosityCoefficient.get(r) * (r - dist);
}