You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
**WaterLily.jl** is a simple and fast fluid simulator written in pure Julia. This project is supported by awesome libraries developed within the Julia scientific community, and it aims to accelerate and enhance fluid simulations. Watch the JuliaCon2024 talk here:
13
14
14
-
[](https://www.youtube.com/live/qru5G5Yp77E?t=29074s)
15
+
[](https://www.youtube.com/watch?v=FwMh2rq9kOU)
15
16
16
17
If you have used WaterLily for research, please __cite us__! The [2024 paper](https://physics.paperswithcode.com/paper/waterlily-jl-a-differentiable-and-backend) describes the main features of the solver and provides benchmarking, validation, and profiling results.
17
18
```
@@ -42,14 +43,14 @@ function circle(n,m;Re=100,U=1)
42
43
radius, center = m/8, m/2-1
43
44
sdf(x,t) =√sum(abs2, x .- center) - radius
44
45
45
-
Simulation((n,m), # domain size
46
+
Simulation((n,m), # domain size
46
47
(U,0), # domain velocity (& velocity scale)
47
48
2radius; # length scale
48
-
ν=U*2radius/Re, # fluid viscosity
49
+
ν=U*2radius/Re, # fluid viscosity
49
50
body=AutoBody(sdf)) # geometry
50
51
end
51
52
```
52
-
The circle geometry is defined using a [signed distance function](https://en.wikipedia.org/wiki/Signed_distance_function#Applications). The `AutoBody` function uses [automatic differentiation](https://github.com/JuliaDiff/) to infer the other geometric parameters of the body automatically. Replace the circle's distance function with any other, and now you have the flow around something else... such as a [donut](https://github.com/WaterLily-jl/WaterLily-Examples/blob/main/examples/ThreeD_Donut.jl) or the [Julia logo](https://github.com/WaterLily-jl/WaterLily-Examples/blob/main/examples/TwoD_Julia.jl). For more complex geometries, [ParametricBodies.jl](https://github.com/WaterLily-jl/ParametricBodies.jl) defines a `body` using any parametric curve, such as a spline. See that repo (and the video above) for examples.
53
+
The circle geometry is defined using a [signed distance function](https://en.wikipedia.org/wiki/Signed_distance_function#Applications). The `AutoBody` function uses [automatic differentiation](https://github.com/JuliaDiff/) to infer the other geometric parameters of the body automatically. Replace the circle's distance function with any other, and now you have the flow around something else... such as a [donut](https://github.com/WaterLily-jl/WaterLily-Examples/blob/main/examples/ThreeD_Donut.jl) or the [Julia logo](https://github.com/WaterLily-jl/WaterLily-Examples/blob/main/examples/TwoD_Julia.jl). For more complex geometries, [ParametricBodies.jl](https://github.com/WaterLily-jl/ParametricBodies.jl) defines a `body` using any parametric curve, such as a spline. See that repo (and the video above) for examples.
53
54
54
55
The code block above return a `Simulation` with the parameters we've defined. Now we can initialize a simulation (first line) and step it forward in time (second line)
55
56
```julia
@@ -66,9 +67,9 @@ contourf(u') # transpose the array for the plot
66
67
```
67
68

68
69
69
-
As you can see, the velocity within the circle is zero, the velocity far from the circle is one, and there are accelerated and decelerated regions around the circle. The `sim_step!` has only taken a single time step, and this initial flow around our circle looks similar to the potential flow because the viscous boundary layer has not separated yet.
70
+
As you can see, the velocity within the circle is zero, the velocity far from the circle is one, and there are accelerated and decelerated regions around the circle. The `sim_step!` has only taken a single time step, and this initial flow around our circle looks similar to the potential flow because the viscous boundary layer has not separated yet.
70
71
71
-
A set of [flow metric functions](https://github.com/WaterLily-jl/WaterLily.jl/blob/master/src/Metrics.jl) have been implemented, and we can use them to measure the simulation. The following code block defines a function to step the simulation to time `t` and then use the `pressure_force` metric to measure the force on the immersed body. The function is applied over a time range, and the forces are plotted.
72
+
A set of [flow metric functions](https://github.com/WaterLily-jl/WaterLily.jl/blob/master/src/Metrics.jl) have been implemented, and we can use them to measure the simulation. The following code block defines a function to step the simulation to time `t` and then use the `pressure_force` metric to measure the force on the immersed body. The function is applied over a time range, and the forces are plotted.
72
73
```Julia
73
74
functionget_forces!(sim,t)
74
75
sim_step!(sim,t,remeasure=false)
@@ -81,7 +82,7 @@ time = 1:0.1:50 # time scale is sim.L/sim.U
81
82
forces = [get_forces!(circ,t) for t in time];
82
83
83
84
#Plot it
84
-
plot(time,[first.(forces), last.(forces)],
85
+
plot(time,[first.(forces), last.(forces)],
85
86
labels=permutedims(["drag","lift"]),
86
87
xlabel="tU/L",
87
88
ylabel="Pressure force coefficients")
@@ -109,7 +110,7 @@ As you can see, WaterLily correctly predicts that the flow is unsteady, with an
109
110
110
111
WaterLily uses [KernelAbstractions.jl](https://github.com/JuliaGPU/KernelAbstractions.jl) to multi-thread on CPU and run on GPU backends. The implementation method and speed-up are documented in the [2024 paper](https://physics.paperswithcode.com/paper/waterlily-jl-a-differentiable-and-backend), with costs as low as 1.44 nano-seconds measured per degree of freedom and time step!
111
112
112
-
Note that multi-threading requires _starting_ Julia with the `--threads` argument, see [the multi-threading section](https://docs.julialang.org/en/v1/manual/multi-threading/) of the manual. If you are running Julia with multiple threads, KernelAbstractions will detect this and multi-thread the loops automatically.
113
+
Note that multi-threading requires _starting_ Julia with the `--threads` argument, see [the multi-threading section](https://docs.julialang.org/en/v1/manual/multi-threading/) of the manual. If you are running Julia with multiple threads, KernelAbstractions will detect this and multi-thread the loops automatically.
113
114
114
115
Running on a GPU requires initializing the `Simulation` memory on the GPU, and care needs to be taken to move the data back to the CPU for visualization. As an example, let's compare a **3D** GPU simulation of a sphere to the **2D** multi-threaded CPU circle defined above
115
116
```Julia
@@ -123,7 +124,7 @@ function sphere(n,m;Re=100,U=1,T=Float64,mem=Array)
123
124
mem) # memory type
124
125
end
125
126
126
-
@assert CUDA.functional() # is your CUDA GPU working??
127
+
@assert CUDA.functional() # is your CUDA GPU working??
127
128
GPUsim =sphere(3*2^5,2^6;T=Float32,mem=CuArray); # 3D GPU sim!
0 commit comments