-
Notifications
You must be signed in to change notification settings - Fork 0
/
index.html
247 lines (220 loc) · 10.9 KB
/
index.html
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
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
<!DOCTYPE html>
<html lang="en" xmlns="http://www.w3.org/1999/xhtml" xmlns:fb="http://ogp.me/ns/fb#">
<head>
<meta charset="utf-8">
<meta property="og:image" content="https://anicusan.github.io/fluid_sim/imgs/preview.png" />
<meta property="og:image:width" content="1387"/>
<meta property="og:image:height" content="820"/>
<title>Fluid Simulation</title>
<meta name="description" content="Javascript app that simulates the Stokes Flow around a falling sphere for low Reynolds Numbers. Meant as a lab auxiliary for the University of Birmingham.">
<meta name="author" content="Andrei Leonard Nicusan, 2018">
<meta name="keywords" content="Javascript, JS, app, simulation, Stokes, Stokes flow, flow, sphere, Reynolds number, Reynolds, lab, lab auxiliary, WebGL, canvas, HTML canvas, HTML, web, falling sphere, viscosity, jacobi, jacobi iterations, Navier-Stokes, Navier, equations, faster, slower">
<link rel="icon" href="./imgs/favicon-96x96.png">
<script src="https://cdnjs.cloudflare.com/ajax/libs/mathjs/5.0.4/math.min.js"></script>
<script
src="https://code.jquery.com/jquery-3.3.1.min.js"
integrity="sha256-FgpCb/KJQlLNfOu91ta32o/NMZxltwRo8QtmkMRdAu8="
crossorigin="anonymous"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/mathjax/2.7.5/MathJax.js?config=TeX-MML-AM_CHTML"></script>
<link href="https://fonts.googleapis.com/css?family=Montserrat" rel="stylesheet">
<link rel="stylesheet" type="text/css" href="css/normalize.css">
<link rel="stylesheet" type="text/css" href="css/styles.css?v=1.0">
<!--[if lt IE 9]>
<script src="https://cdnjs.cloudflare.com/ajax/libs/html5shiv/3.7.3/html5shiv.js"></script>
<![endif]-->
</head>
<body>
<div class="top_container">
<div class="top_menu">
<button class="top_buttons" id="reset">Reset</button>
<button class="top_buttons" id="help">Info</button>
<button class="top_text">Time: </button>
<button class="button_time half" id="4x_slower">4x ◀◀</button>
<button class="button_time half" id="2x_slower">2x ◀◀</button>
<button class="button_time half" style="font-size: 22px;" id="stop_sim">‖</button>
<button class="button_time half" id="real_time">▶</button>
<button class="button_time half" id="2x_faster">2x ▶▶</button>
<button class="button_time half" id="4x_faster">4x ▶▶</button>
<div class="top_space"></div>
<button class="top_text">Viscosity: </button>
<button class="button_viscosity" id="cst50">50 cSt</button>
<button class="button_viscosity" id="cst500">500 cSt</button>
<button class="button_viscosity" id="cst5000">5,000 cSt</button>
<button class="button_viscosity" id="cst30000">30,000 cSt</button>
<div class="top_space"></div>
<button class="top_text">Jacobi iterations: </button>
<button class="button_jacobi half" id="jacobi_minus">▼</button>
<button class="button_jacobi half" id="jacobi_disp"></button>
<button class="button_jacobi half" id="jacobi_plus">▲</button>
<div class="top_space"></div>
</div>
</div>
<div class="modal_container" id="helpDiv">
<div class="modal_content">
<p>
<h1>Introduction</h1>
<p>This is a web app that simulates the fluid flow around a falling sphere,
taking into account the dynamic effects of fluid viscosity, sphere radius
and density, along with static parameters such as gravity, buoyancy and drag.</p>
<p>The simulation measures the time taken for the sphere to travel 15cm at terminal
velocity. It is meant as a lab auxiliary for the Chemical Engineering course at
the University of Birmingham.</p>
<h1>Usage</h1>
<p>The simulation parameters can be changed from the menus at the top of the
screen. The time can be altered from real time to 4 times slower or 4 times
faster. The viscosity is measured in centistokes (cSt).</p>
<p>Any sphere can be selected by clicking on it. The radius is provided in
imperial measurements, like the laboratory resources.</p>
<p>At the bottom of the screen is the table for physical, dynamic parameters.
On the right is the data log that outputs the measurements.</p>
<p>The Jacobi iterations parameter represents the number of calculations for
the fluid movement. A higher number of iterations provides higher fidelity in the
fluid flow, but requires more power from the GPU.</p>
<p>More in-depth information is given in the next section.</p>
<h1>Technicalities</h1>
<p>The graphical fluid flow is modelled using the Navier-Stokes equations:
$$\frac{\partial \vec{u}}{\partial t} = -\vec{u} \cdot \nabla \vec{u} - \frac{1}{\rho}\nabla \rho + \nu \nabla^2\vec{u} + \vec{F}$$
$$\nabla \cdot \vec{u} = 0$$
However, for purely graphical purposes, leaving the viscosity term out provides
a very good trade-off in terms of computational efficiency and graphical fidelity.
The equations are solved numerically for pressure using Jacobi iterations.</p>
<p>The graphical sphere movement is modelled using gravitational acceleration,
drag force and buoyancy. The sphere moves in discrete time-steps of around 0.065ms.
Therefore, at terminal velocity, the following is true:
$$ m g = C_d A \frac {\rho u^2}{2} + \rho V g $$
The drag coefficient C<sub>d</sub> is defined in terms of the Reynolds Number:
$$ Re = \frac {\rho u d}{\mu} $$
<ul>
<li>For Stokes' flow (Re < 0.2) $$C_d = \frac{24}{Re}$$</li>
<li>For Allen flow (0.2 < Re < 1000) $$C_d = \frac{24}{Re} (1 + 0.15 Re^{0.687})$$</li>
<li>For Newton flow (1000 < Re < 2x10<sup>5</sup>) $$C_d = 0.44$$</li>
<li>For Re > 2x10<sup>5</sup> $$C_d= 0.11$$</li>
</ul>
</p>
<p>The simulation screen is comprised of two superimposed HTML canvases:
<ul>
<li>The fluid simulation is in the background and is rendered on the GPU.</li>
<li>The sphere movement is in the foreground and is rendered on the CPU.</li>
</ul></p>
<p>The programming technicalities can be accessed in the well-commented javascript file
fluid-sim.js. I have written it to be as modular and intuitive as possible. It is
available in this website's sources in the developer menu, as well as on my
<a href="https://github.com/anicusan/anicusan.github.io/tree/master/fluid_sim">github account</a></p>
<h1>References and Further Reading</h1>
<p>To make this, I had to draw from many different sources. The main ones are:
<ul>
<li><a href="http://jamie-wong.com/2016/08/05/webgl-fluid-simulation/#navier-stokes">Jamie-Wong's
WebGL Fluid Simulation:</a> This is by far the most important resource I used. It describes the
mathematical-computational concepts used for fluid simulation in a very user-friendly format. I
used most of the WebGL code from here, updating all the libraries and enhancing numerical stability.</li>
<li><a href="http://developer.download.nvidia.com/books/HTML/gpugems/gpugems_ch38.html">GPU Gems
Chapter 38. Fast Fluid Dynamics Simulation on the GPU:</a> It walks through specific implementation
ideas, and gave me a much better intuition for advection. It is written in a much more technical
language, being more of a scientific paper.</li>
<li><a href="https://29a.ch/sandbox/2012/fluidcanvas/">Jonas Wagner’s fluid simulation on canvas </a>
and particularly the source for it (fluid.js) were helpful for understanding what a full solution
actually looks like.</li>
<li><a href="http://apps.amandaghassaei.com/VortexShedding/#">Amanda Ghassaei vortex shedding
simulation: </a> I used this to analyse vortex formation and actual coding of the simulation.</li>
<li><a href="https://burakkanber.com/blog/modeling-physics-javascript-gravity-and-drag/"> Burak
Kanber's modelling physics in javascript: </a> I used this as a tutorial for modelling forces
in javascript and rendering them in an HTML canvas.</li>
<li><a href="https://github.com/evanw/lightgl.js/">Evan Wallace's LightGL library:</a> This
javascript library provides a very light abstraction layer on top of WebGL. Very helpful for
prototyping the simulation on the GPU.</li>
<li>Dr. Phillip Robbins, Senior Lecturer of the School of Chemical Engineering of the University
of Birmingham: I got the lab description and the physical properties of the lab resources from the
exercise paper written by Dr. Robbins.</li>
<li>Many thanks for also having Ciara Albas-Martin MEng and Marten Reichow MEng conduct this
experiment in the lab and taking lots of measurements.</li>
</ul></p>
</p>
<button id="closeHelp">Close</button>
<script type="text/javascript">
var helpDiv = document.getElementById('helpDiv');
var openHelp = document.getElementById("help");
var closeHelp = document.getElementById("closeHelp");
openHelp.onclick = function() {
$(helpDiv).fadeIn(400);
document.getElementById("stop_sim").click();
}
closeHelp.onclick = function() {
$(helpDiv).fadeOut(400);
}
window.onclick = function(event) {
if (event.target == helpDiv) {
$(helpDiv).fadeOut(400);
}
}
</script>
</div>
</div>
<div class="container">
<canvas id="sphere_selection">Use a better browser!</canvas>
</div>
<div class="black_wrapper">
<div class="container" id="fluid_screen">
<canvas id="fluid">Use a better device!</canvas>
<canvas id="sphere">Use a better browser!</canvas>
</div>
</div>
<table class="data_table">
<tr>
<td colspan="2">Acceleration (m / s<sup>2</sup>)</td>
<td colspan="2">Velocity (m / s)</td>
<td colspan="2">Position (m)</td>
<td rowspan="5" class="col_log">
<div id="data_log"></div>
</td>
</tr>
<tr>
<td colspan="2" id="acc"></td>
<td colspan="2" id="vel"></td>
<td colspan="2"> - </td>
</tr>
<tr>
<td>x</td>
<td>y</td>
<td>x</td>
<td>y</td>
<td>x</td>
<td>y</td>
</tr>
<tr>
<td id="acc_x">accx</td>
<td id="acc_y">accy</td>
<td id="vel_x">velx</td>
<td id="vel_y">vely</td>
<td id="pos_x">posx</td>
<td id="pos_y">posy</td>
</tr>
<tr>
<td colspan="3" class="log_buttons"><div id="exportCSV">Export to CSV</div></td>
<td colspan="3" class="log_buttons"><div id="clearLog">Clear Log</div></td>
</tr>
</table>
<ul class="footer_meta">
<li>Andrei Leonard Nicusan, 2018</li>
<li style="margin: 10px;"> | </li>
<li>University of Birmingham</li>
<li style="margin: 10px;"> | </li>
<li>License: <strong>GNU v3.0</strong></li>
</ul>
<script type="text/javascript" src="js/lightgl.js"></script>
<script type="text/javascript" src="js/fluid-sim.js"></script>
<script type="text/javascript">
var canvasSize = 800;
console.log($(window).height());
new FluidSim("fluid", "sphere", "sphere_selection", {
threshold: false,
advectV: true,
applyPressure: true,
showArrows: true,
size: canvasSize,
dim: 1,
initVFn: ['0.0', '0.0'],
dyeSpots: false,
});
</script>
</body>
</html>