Skip to content

Commit e3c2767

Browse files
authored
Merge pull request #83 from maltezfaria/narrow-band
Narrow band implementation and major refactoring.
2 parents cab7e8d + 58a3794 commit e3c2767

43 files changed

Lines changed: 2959 additions & 1107 deletions

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,3 +18,4 @@ sandbox
1818
*.msh
1919
*.sol
2020
*.mesh
21+
*.markdown-preview.html

docs/src/boundary-conditions.md

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -7,10 +7,10 @@ The following boundary conditions are available:
77
| [`PeriodicBC`](@ref) | Periodic (wrap-around) |
88
| [`DirichletBC`](@ref) | Prescribed boundary value |
99
| [`ExtrapolationBC{P}`](@ref ExtrapolationBC) | P-th order one-sided polynomial extrapolation |
10-
| `NeumannBC` | Alias for `ExtrapolationBC{1}` (constant extension, ∂ϕ/∂n = 0) |
11-
| `NeumannGradientBC` | Alias for `ExtrapolationBC{2}` (linear extrapolation, ∂²ϕ/∂n² = 0) |
10+
| `NeumannBC` | Alias for `ExtrapolationBC{0}` (constant extension, ∂ϕ/∂n = 0) |
11+
| `LinearExtrapolationBC` | Alias for `ExtrapolationBC{1}` (linear extrapolation, ∂²ϕ/∂n² = 0) |
1212

13-
`ExtrapolationBC{P}` uses the `P` nearest interior cells to build a degree `P-1` polynomial
13+
`ExtrapolationBC{P}` uses the `P+1` nearest interior cells to build a degree-`P` polynomial
1414
and extrapolates it into the ghost region. Higher `P` gives smoother outflow at the cost of
1515
a wider stencil.
1616

@@ -32,7 +32,7 @@ using LevelSetMethods, GLMakie
3232
grid = CartesianGrid((-1,-1), (1,1), (100, 100))
3333
ϕ₀ = LevelSet(x -> sqrt(x[1]^2 + x[2]^2) - 0.5, grid)
3434
bc = PeriodicBC()
35-
eq = LevelSetEquation(; levelset = deepcopy(ϕ₀), bc, terms = AdvectionTerm((x,t) -> (1,0)))
35+
eq = LevelSetEquation(; ic = deepcopy(ϕ₀), bc, terms = AdvectionTerm((x,t) -> (1,0)))
3636
fig = Figure(; size = (1200, 300))
3737
for (n,t) in enumerate([0.0, 0.5, 0.75, 1.0])
3838
integrate!(eq, t)
@@ -42,10 +42,10 @@ end
4242
fig
4343
```
4444

45-
Changing `PeriodicBC()` to `NeumannBC()` gives allows for the level-set to "leak" out of the domain:
45+
Changing `PeriodicBC()` to `NeumannBC()` allows the level-set to "leak" out of the domain:
4646

4747
```@example boundary-conditions
48-
eq = LevelSetEquation(; levelset = deepcopy(ϕ₀), bc = NeumannBC(), terms = AdvectionTerm((x,t) -> (1,0)))
48+
eq = LevelSetEquation(; ic = deepcopy(ϕ₀), bc = NeumannBC(), terms = AdvectionTerm((x,t) -> (1,0)))
4949
fig = Figure(; size = (1200, 300))
5050
for (n,t) in enumerate([0.0, 0.5, 0.75, 1.0])
5151
integrate!(eq, t)
@@ -59,7 +59,7 @@ To combine both boundary conditions you can use
5959

6060
```@example boundary-conditions
6161
bc = (NeumannBC(), PeriodicBC()) # Neumann in x, periodic in y
62-
eq = LevelSetEquation(; levelset = deepcopy(ϕ₀), bc, terms = AdvectionTerm((x,t) -> (1,1)))
62+
eq = LevelSetEquation(; ic = deepcopy(ϕ₀), bc, terms = AdvectionTerm((x,t) -> (1,1)))
6363
fig = Figure(; size = (1200, 300))
6464
for (n,t) in enumerate([0.0, 0.5, 0.75, 1.0])
6565
integrate!(eq, t)
@@ -70,11 +70,11 @@ fig
7070
```
7171

7272
For higher-order outflow you can use `ExtrapolationBC{P}` directly. For example,
73-
`ExtrapolationBC{5}` fits a degree-4 polynomial through the 5 nearest interior cells:
73+
`ExtrapolationBC{5}` fits a degree-5 polynomial through the 6 nearest interior cells:
7474

7575
```@example boundary-conditions
7676
bc = ExtrapolationBC(5)
77-
eq = LevelSetEquation(; levelset = deepcopy(ϕ₀), bc, terms = AdvectionTerm((x,t) -> (1,0)))
77+
eq = LevelSetEquation(; ic = deepcopy(ϕ₀), bc, terms = AdvectionTerm((x,t) -> (1,0)))
7878
fig = Figure(; size = (1200, 300))
7979
for (n,t) in enumerate([0.0, 0.5, 0.75, 1.0])
8080
integrate!(eq, t)

docs/src/example-mass-conservation.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,7 @@ timestamps = range(0, tf; length = nframes + 1)
3939
function track_volume(integrator)
4040
ϕ = deepcopy(ϕ₀)
4141
eq = LevelSetEquation(;
42-
levelset = ϕ,
42+
ic = ϕ,
4343
terms = AdvectionTerm((x, t) -> (-x[2], x[1])),
4444
bc = NeumannBC(),
4545
integrator,

docs/src/example-shape-optim.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -93,9 +93,9 @@ term1 = NormalMotionTerm(MeshField(X -> 0.0, grid))
9393
term2 = CurvatureTerm(MeshField(X -> -1.0, grid))
9494
terms = (term1, term2)
9595
96-
bc = NeumannGradientBC()
96+
bc = LinearExtrapolationBC()
9797
integrator = ForwardEuler(0.5)
98-
eq = LevelSetEquation(; terms, integrator, levelset = ϕ, t = 0, bc)
98+
eq = LevelSetEquation(; terms, integrator, ic = ϕ, t = 0, bc)
9999
100100
using GLMakie
101101

docs/src/example-zalesak.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,7 @@ simulates rotation:
4040
```@example zalesak_disk_example
4141
# Define the advection equation with a rotational velocity field
4242
eq = LevelSetEquation(;
43-
levelset = ϕ,
43+
ic = ϕ,
4444
terms = AdvectionTerm((x, t) -> (-x[2], x[1])),
4545
bc = NeumannBC(),
4646
)
@@ -97,7 +97,7 @@ rec = LevelSetMethods.rectangle(
9797
)
9898
ϕ = setdiff(disk, rec)
9999
eq = LevelSetEquation(;
100-
levelset = ϕ,
100+
ic = ϕ,
101101
terms = AdvectionTerm((x, t) -> π * SVector(x[2], -x[1], 0)),
102102
bc = NeumannBC(),
103103
)

docs/src/extension-mmg.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
# [MMG extension](@id extension-mmg)
22

3-
This extension provides functions to generate meshes of level-set functions using [MMG](https://www.mmgtools.org/).
3+
This extension provides functions to generate meshes of level-set functions using [MMG](https://github.com/MmgTools/mmg).
44
It defines two methods: `export_volume_mesh` and `export_surface_mesh`.
55
For both of them, it is possible to control the size of the generated mesh using the following optional parameters:
66

docs/src/index.md

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -44,8 +44,8 @@ grid = CartesianGrid((-1, -1), (1, 1), (100, 100))
4444
𝐮 = (x,t) -> (-x[2], x[1])
4545
eq = LevelSetEquation(;
4646
terms = (AdvectionTerm(𝐮),),
47-
levelset = ϕ,
48-
bc = PeriodicBC()
47+
ic = ϕ,
48+
bc = NeumannBC()
4949
)
5050
```
5151

@@ -99,10 +99,10 @@ Here is what the `.gif` file looks like:
9999
For more interesting applications and advanced usage, see the examples section!
100100

101101
!!! note "Other resources"
102-
There is an almost one-to-one correspondance between each of the [`LevelSetTerm`](@ref)s
103-
described above and individual chapters of the book by Osher and Fedwick on level set
102+
There is an almost one-to-one correspondence between each of the [`LevelSetTerm`](@ref)s
103+
described above and individual chapters of the book by Osher and Fedkiw on level set
104104
methods [osher2003level](@cite), so users interested in digging deeper into the
105-
theory/algorithms are encourage to consult that refenrence. We also drew some
105+
theory/algorithms are encouraged to consult that reference. We also drew some
106106
inspiration from the great Matlab library `ToolboxLS` by Ian Mitchell
107107
[mitchell2007toolbox](@cite).
108108

docs/src/interpolation.md

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -15,13 +15,13 @@ using LevelSetMethods
1515
a, b = (-2.0, -2.0), (2.0, 2.0)
1616
ϕ = LevelSetMethods.star(CartesianGrid(a, b, (50, 50)))
1717
# Add boundary conditions for safe evaluation near edges
18-
bc = ntuple(_ -> (NeumannGradientBC(), NeumannGradientBC()), 2)
18+
bc = ntuple(_ -> (LinearExtrapolationBC(), LinearExtrapolationBC()), 2)
1919
ϕ = LevelSetMethods.add_boundary_conditions(ϕ, bc)
2020
2121
itp = interpolate(ϕ) # cubic interpolation by default (order=3)
2222
```
2323

24-
The returned object is a [`PiecewisePolynomialInterpolation`](@ref LevelSetMethods.PiecewisePolynomialInterpolation), which is callable and
24+
The returned object is a [`PiecewisePolynomialInterpolant`](@ref LevelSetMethods.PiecewisePolynomialInterpolant), which is callable and
2525
efficient. Once constructed, the interpolant can be used to evaluate the level-set function
2626
anywhere inside (and even slightly outside, using boundary conditions) the grid:
2727

@@ -69,7 +69,7 @@ P1, P2 = (-1.0, 0.0, 0.0), (1.0, 0.0, 0.0)
6969
b = 1.05
7070
f = (x) -> norm(x .- P1)*norm(x .- P2) - b^2
7171
ϕ3 = LevelSet(f, grid)
72-
bc3 = ntuple(_ -> (NeumannGradientBC(), NeumannGradientBC()), 3)
72+
bc3 = ntuple(_ -> (LinearExtrapolationBC(), LinearExtrapolationBC()), 3)
7373
ϕ3 = LevelSetMethods.add_boundary_conditions(ϕ3, bc3)
7474
7575
itp3 = interpolate(ϕ3)

docs/src/reinitialization.md

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -56,8 +56,8 @@ Pass `reinit` to [`LevelSetEquation`](@ref) to reinitialize automatically every
5656
```julia
5757
eq = LevelSetEquation(;
5858
terms = (AdvectionTerm(𝐮),),
59-
levelset = ϕ,
60-
bc = PeriodicBC(),
59+
ic = ϕ,
60+
bc = NeumannBC(),
6161
reinit = 5, # reinitialize every 5 time steps
6262
)
6363
```
@@ -69,8 +69,8 @@ directly:
6969
```julia
7070
eq = LevelSetEquation(;
7171
terms = (AdvectionTerm(𝐮),),
72-
levelset = ϕ,
73-
bc = PeriodicBC(),
72+
ic = ϕ,
73+
bc = NeumannBC(),
7474
reinit = NewtonReinitializer(; reinit_freq = 5, upsample = 4),
7575
)
7676
```

docs/src/terms.md

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,7 @@ grid points. Lets construct a level-set equation with an advection term:
4444

4545
```@example advection-term
4646
ϕ₀ = LevelSet(x -> sqrt(x[1]^2 + x[2]^2) - 0.5, grid)
47-
eq = LevelSetEquation(; terms = (AdvectionTerm(𝐮),), levelset = ϕ₀, bc = PeriodicBC())
47+
eq = LevelSetEquation(; terms = (AdvectionTerm(𝐮),), ic = ϕ₀, bc = NeumannBC())
4848
```
4949

5050
To see how the advection term affects the level-set, we can solve the equation for a few
@@ -71,7 +71,7 @@ have instead a time-dependent velocity field, we could pass a function to the
7171

7272
```@example advection-term
7373
ϕ₀ = LevelSet(x -> sqrt(x[1]^2 + x[2]^2) - 0.5, grid)
74-
eq = LevelSetEquation(; terms = (AdvectionTerm((x,t) -> SVector(x[1]^2, 0)),), levelset = ϕ₀, bc = PeriodicBC())
74+
eq = LevelSetEquation(; terms = (AdvectionTerm((x,t) -> SVector(x[1]^2, 0)),), ic = ϕ₀, bc = NeumannBC())
7575
fig = Figure(; size = (1200, 300))
7676
# create a 2 x 2 figure
7777
for (n,t) in enumerate([0.0, 0.5, 0.75, 1.0])
@@ -102,8 +102,8 @@ let us compare both schemes for a purely rotational velocity field:
102102
𝐮 = MeshField(grid) do (x,y)
103103
SVector(-y, x)
104104
end
105-
eq_upwind = LevelSetEquation(; terms = AdvectionTerm(𝐮, Upwind()), levelset = deepcopy(ϕ₀), bc = PeriodicBC())
106-
eq_weno = LevelSetEquation(; terms = AdvectionTerm(𝐮), levelset = deepcopy(ϕ₀), bc = PeriodicBC())
105+
eq_upwind = LevelSetEquation(; terms = AdvectionTerm(𝐮, Upwind()), ic = deepcopy(ϕ₀), bc = NeumannBC())
106+
eq_weno = LevelSetEquation(; terms = AdvectionTerm(𝐮), ic = deepcopy(ϕ₀), bc = NeumannBC())
107107
fig = Figure(size = (1000, 400))
108108
ax = Axis(fig[1,1], title = "Initial")
109109
plot!(ax, eq_upwind)
@@ -134,7 +134,7 @@ using LevelSetMethods
134134
using GLMakie
135135
grid = CartesianGrid((-2,-2), (2,2), (100, 100))
136136
ϕ = LevelSetMethods.star(grid)
137-
eq = LevelSetEquation(; terms = (NormalMotionTerm((x,t) -> 0.5),), levelset = ϕ, bc = PeriodicBC())
137+
eq = LevelSetEquation(; terms = (NormalMotionTerm((x,t) -> 0.5),), ic = ϕ, bc = NeumannBC())
138138
fig = Figure(; size = (1200, 300))
139139
for (n,t) in enumerate([0.0, 0.5, 0.75, 1.0])
140140
integrate!(eq, t)
@@ -185,7 +185,7 @@ where ``\kappa = \nabla \cdot (\nabla \phi / |\nabla \phi|)`` is the mean curvat
185185
coefficient ``b`` should be negative; a positive value of ``b`` would yield an ill-posed
186186
evolution problem (akin to a negative diffusion coefficient).
187187

188-
Here is the classic example of motion by mean curavature for a spiral-like level-set:
188+
Here is the classic example of motion by mean curvature for a spiral-like level-set:
189189

190190
```@example curvature-term
191191
using LevelSetMethods, GLMakie
@@ -208,7 +208,7 @@ M = R * [1/0.06^2 0; 0 1/(4π^2)] * R'
208208
end
209209
return result
210210
end
211-
eq = LevelSetEquation(; terms = (CurvatureTerm((x,t) -> -0.1),), levelset = ϕ, bc = PeriodicBC())
211+
eq = LevelSetEquation(; terms = (CurvatureTerm((x,t) -> -0.1),), ic = ϕ, bc = NeumannBC())
212212
fig = Figure(; size = (1200, 300))
213213
for (n,t) in enumerate([0.0, 0.1, 0.2, 0.3])
214214
integrate!(eq, t)
@@ -253,7 +253,7 @@ fig
253253
We will now evolve the level-set using the reinitialization term:
254254

255255
```@example reinitialization-term
256-
eq = LevelSetEquation(; terms = (EikonalReinitializationTerm(),), levelset = deepcopy(ϕ), bc = PeriodicBC())
256+
eq = LevelSetEquation(; terms = (EikonalReinitializationTerm(),), ic = deepcopy(ϕ), bc = NeumannBC())
257257
fig = Figure(; size = (1200, 300))
258258
for (n,t) in enumerate([0.0, 0.25, 0.5, 0.75])
259259
integrate!(eq, t)
@@ -274,7 +274,7 @@ Alternatively, you can use a modified reinitialization term that applies the sig
274274
To enable this behavior, simply pass a `LevelSet` object to the `EikonalReinitializationTerm`:
275275

276276
```@example reinitialization-term
277-
eq = LevelSetEquation(; terms = (EikonalReinitializationTerm(ϕ),), levelset = deepcopy(ϕ), bc = PeriodicBC())
277+
eq = LevelSetEquation(; terms = (EikonalReinitializationTerm(ϕ),), ic = deepcopy(ϕ), bc = NeumannBC())
278278
fig = Figure(; size = (1200, 300))
279279
for (n,t) in enumerate([0.0, 0.25, 0.5, 0.75])
280280
integrate!(eq, t)

0 commit comments

Comments
 (0)