using TopOpt, LinearAlgebra
using WGLMakie
WGLMakie.activate!(; resize_to=:parent)
using Bonito
if haskey(ENV, "QUARTO_PROJECT_DIR")
Bonito.Page(exportable=true, offline=true)
else
Bonito.browser_display()
end
display_app(app) = display(app)Projected Density Filter for Crisp Black/White Designs
Description
A plain density filter smooths the design and removes checkerboards, but it leaves a wide band of intermediate (“gray”) densities. ProjectedDensityFilterFun combines the density filter with a nonlinear projection (Heaviside or Sigmoid) that pushes filtered densities toward 0 or 1, producing near-binary designs — the standard approach for eliminating gray elements (Sigmund, 2007).
This tutorial compares the plain filter with Heaviside and Sigmoid projections, and shows how to continue the projection steepness parameter β during the optimization.
Setup
WGLMakie.activate!(; resize_to=:parent) selects the browser renderer and fills the Quarto output column. Bonito.Page(exportable=true, offline=true) embeds the assets needed by visualize(...; static=true) in the Quarto output, so the visualization does not require a running Julia process.
The projection functions
HeavisideProjectionFun(β) and SigmoidProjectionFun(β) both map [0, 1] toward {0, 1}, with larger β giving a sharper transition:
for β in (1.0, 4.0, 16.0)
H = HeavisideProjectionFun(β)
S = SigmoidProjectionFun(β)
println("β=$β: Heaviside(0.2)=$(round(H(0.2), digits=3)), $(round(H(0.8), digits=3)); Sigmoid(0.2)=$(round(S(0.2), digits=3)), $(round(S(0.8), digits=3))")
endβ=1.0: Heaviside(0.2)=0.255, 0.845; Sigmoid(0.2)=0.354, 0.646
β=4.0: Heaviside(0.2)=0.554, 0.974; Sigmoid(0.2)=0.182, 0.818
β=16.0: Heaviside(0.2)=0.959, 1.0; Sigmoid(0.2)=0.006, 0.994
Define the problem
E, ν, f = 1.0, 0.3, 1.0
nels = (60, 20)
problem = HalfMBB(nels, (1.0, 1.0), E, ν, f)
solver = FEASolver(DirectSolver, problem; xmin=0.001, penalty=PowerPenaltyFun(3.0))
comp = ComplianceFun(solver)
volfrac = VolumeFun(solver)
V = 0.5
rmin = 2.0
N = prod(nels)
x0 = fill(V, N)
grayness(x) = count(0.1 .< x .< 0.9) / length(x)
function solve_with(filt)
obj = x -> comp(filt(PseudoDensities(x)))
constr = x -> volfrac(filt(PseudoDensities(x))) - V
model = Model(obj)
addvar!(model, zeros(N), ones(N))
add_ineq_constraint!(model, constr)
r = optimize(model, MMA87(), x0;
options=MMAOptions(; maxiter=120, tol=Tolerance(; kkt=1e-4, f=1e-4)))
topo = filt(PseudoDensities(r.minimizer)).x
println("compliance = $(round(obj(r.minimizer), digits=2)), vol = $(round(constr(r.minimizer) + V, digits=3)), gray = $(round(grayness(topo), digits=3))")
return topo
endPlain density filter (baseline)
plain_filter = DensityFilterFun(solver; rmin=rmin)
topo_plain = solve_with(plain_filter)[ Info: iter obj Δobj violation kkt_residual [ Info: 0 9.1e+02 Inf 0.0e+00 7.0e+01 [ Info: 1 6.1e+02 2.9e+02 0.0e+00 1.6e+02 [ Info: 2 4.2e+02 1.9e+02 0.0e+00 3.7e+01 [ Info: 3 3.6e+02 6.7e+01 0.0e+00 1.3e+01 [ Info: 4 3.3e+02 2.5e+01 0.0e+00 5.3e+00 [ Info: 5 3.2e+02 1.4e+01 0.0e+00 3.4e+00 [ Info: 6 3.1e+02 9.9e+00 0.0e+00 2.4e+00 [ Info: 7 3.0e+02 7.5e+00 0.0e+00 1.8e+00 [ Info: 8 2.9e+02 6.7e+00 0.0e+00 1.7e+00 [ Info: 9 2.9e+02 6.3e+00 0.0e+00 1.6e+00 [ Info: 10 2.8e+02 6.2e+00 0.0e+00 1.5e+00 [ Info: 11 2.7e+02 7.0e+00 0.0e+00 1.7e+00 [ Info: 12 2.7e+02 8.2e+00 0.0e+00 1.9e+00 [ Info: 13 2.6e+02 1.1e+01 0.0e+00 2.4e+00 [ Info: 14 2.4e+02 1.2e+01 0.0e+00 2.4e+00 [ Info: 15 2.3e+02 1.1e+01 0.0e+00 2.1e+00 [ Info: 16 2.3e+02 5.8e+00 0.0e+00 1.0e+00 [ Info: 17 2.2e+02 3.9e+00 0.0e+00 7.7e-01 [ Info: 18 2.2e+02 3.5e+00 0.0e+00 7.0e-01 [ Info: 19 2.2e+02 2.8e+00 0.0e+00 5.4e-01 [ Info: 20 2.2e+02 1.5e+00 0.0e+00 4.1e-01 [ Info: 21 2.1e+02 1.1e+00 0.0e+00 4.3e-01 [ Info: 22 2.1e+02 8.9e-01 0.0e+00 3.9e-01 [ Info: 23 2.1e+02 7.1e-01 0.0e+00 1.9e-01 [ Info: 24 2.1e+02 5.6e-01 0.0e+00 1.8e-01 [ Info: 25 2.1e+02 4.7e-01 0.0e+00 1.7e-01 [ Info: 26 2.1e+02 3.2e-01 0.0e+00 1.8e-01 [ Info: 27 2.1e+02 1.4e-01 0.0e+00 1.7e-01 [ Info: 28 2.1e+02 7.7e-02 0.0e+00 1.0e-01 [ Info: 29 2.1e+02 5.6e-02 0.0e+00 9.4e-02 [ Info: 30 2.1e+02 3.9e-02 0.0e+00 7.3e-02 [ Info: 31 2.1e+02 3.2e-02 0.0e+00 5.3e-02 [ Info: 32 2.1e+02 2.7e-02 0.0e+00 4.5e-02 [ Info: 33 2.1e+02 2.3e-02 0.0e+00 2.9e-02 [ Info: 34 2.1e+02 1.5e-02 0.0e+00 2.8e-02 [ Info: 35 2.1e+02 1.1e-02 0.0e+00 2.4e-02 [ Info: 36 2.1e+02 8.6e-03 0.0e+00 2.2e-02 [ Info: 37 2.1e+02 6.0e-03 0.0e+00 2.2e-02 [ Info: 38 2.1e+02 4.6e-03 0.0e+00 1.7e-02 [ Info: 39 2.1e+02 3.5e-03 0.0e+00 1.7e-02 [ Info: 40 2.1e+02 2.7e-03 0.0e+00 1.4e-02 [ Info: 41 2.1e+02 1.9e-03 0.0e+00 1.2e-02 [ Info: 42 2.1e+02 1.3e-03 0.0e+00 9.0e-03 [ Info: 43 2.1e+02 1.0e-03 0.0e+00 7.5e-03 [ Info: 44 2.1e+02 8.2e-04 0.0e+00 5.4e-03 [ Info: 45 2.1e+02 6.6e-04 0.0e+00 4.4e-03 [ Info: 46 2.1e+02 5.3e-04 0.0e+00 3.3e-03 [ Info: 47 2.1e+02 4.3e-04 0.0e+00 3.3e-03 [ Info: 48 2.1e+02 3.6e-04 0.0e+00 2.5e-03 [ Info: 49 2.1e+02 3.1e-04 0.0e+00 2.8e-03 [ Info: 50 2.1e+02 2.6e-04 0.0e+00 2.3e-03 [ Info: 51 2.1e+02 2.2e-04 0.0e+00 3.0e-03 [ Info: 52 2.1e+02 2.0e-04 0.0e+00 2.2e-03 [ Info: 53 2.1e+02 1.7e-04 0.0e+00 3.2e-03 [ Info: 54 2.1e+02 1.5e-04 0.0e+00 2.4e-03 [ Info: 55 2.1e+02 1.3e-04 0.0e+00 3.6e-03 [ Info: 56 2.1e+02 1.1e-04 0.0e+00 2.6e-03 [ Info: 57 2.1e+02 1.1e-04 0.0e+00 2.7e-03 [ Info: 58 2.1e+02 9.7e-05 0.0e+00 2.0e-03 [ Info: 59 2.1e+02 6.9e-05 0.0e+00 1.7e-03 [ Info: 60 2.1e+02 5.4e-05 0.0e+00 1.7e-03 [ Info: 61 2.1e+02 4.6e-05 0.0e+00 1.5e-03 [ Info: 62 2.1e+02 3.6e-05 0.0e+00 2.0e-03 [ Info: 63 2.1e+02 3.5e-05 0.0e+00 1.9e-03 [ Info: 64 2.1e+02 2.8e-05 0.0e+00 2.3e-03 [ Info: 65 2.1e+02 2.7e-05 0.0e+00 2.1e-03 [ Info: 66 2.1e+02 2.6e-05 0.0e+00 2.5e-03 [ Info: 67 2.1e+02 2.4e-05 0.0e+00 2.1e-03 [ Info: 68 2.1e+02 1.9e-05 0.0e+00 2.5e-03 [ Info: 69 2.1e+02 1.5e-05 0.0e+00 1.8e-03 [ Info: 70 2.1e+02 2.1e-05 0.0e+00 2.3e-03 [ Info: 71 2.1e+02 1.6e-05 0.0e+00 1.6e-03 [ Info: 72 2.1e+02 2.3e-05 0.0e+00 1.9e-03 [ Info: 73 2.1e+02 1.7e-05 0.0e+00 1.5e-03 [ Info: 74 2.1e+02 2.2e-05 0.0e+00 1.4e-03 [ Info: 75 2.1e+02 1.9e-05 0.0e+00 1.2e-03 [ Info: 76 2.1e+02 2.0e-05 0.0e+00 1.1e-03 [ Info: 77 2.1e+02 1.7e-05 0.0e+00 1.0e-03 [ Info: 78 2.1e+02 1.6e-05 0.0e+00 9.5e-04 [ Info: 79 2.1e+02 1.5e-05 0.0e+00 8.8e-04 [ Info: 80 2.1e+02 1.3e-05 0.0e+00 8.3e-04 [ Info: 81 2.1e+02 1.3e-05 0.0e+00 7.7e-04 [ Info: 82 2.1e+02 1.2e-05 0.0e+00 7.2e-04 [ Info: 83 2.1e+02 1.2e-05 0.0e+00 7.1e-04 [ Info: 84 2.1e+02 1.2e-05 0.0e+00 7.0e-04 [ Info: 85 2.1e+02 1.2e-05 0.0e+00 7.1e-04 [ Info: 86 2.1e+02 1.2e-05 0.0e+00 7.1e-04 [ Info: 87 2.1e+02 1.2e-05 0.0e+00 7.3e-04 [ Info: 88 2.1e+02 1.3e-05 0.0e+00 7.4e-04 [ Info: 89 2.1e+02 1.3e-05 0.0e+00 7.6e-04 [ Info: 90 2.1e+02 1.4e-05 0.0e+00 7.6e-04 [ Info: 91 2.1e+02 1.4e-05 0.0e+00 7.5e-04 [ Info: 92 2.1e+02 1.4e-05 0.0e+00 7.5e-04 [ Info: 93 2.1e+02 1.5e-05 0.0e+00 7.4e-04 [ Info: 94 2.1e+02 1.5e-05 0.0e+00 7.4e-04 [ Info: 95 2.1e+02 1.6e-05 0.0e+00 7.1e-04 [ Info: 96 2.1e+02 1.6e-05 0.0e+00 7.2e-04 [ Info: 97 2.1e+02 1.8e-05 0.0e+00 6.8e-04 [ Info: 98 2.1e+02 1.8e-05 0.0e+00 7.2e-04 [ Info: 99 2.1e+02 2.0e-05 0.0e+00 7.0e-04 [ Info: 100 2.1e+02 2.0e-05 0.0e+00 7.4e-04 [ Info: 101 2.1e+02 2.3e-05 0.0e+00 7.7e-04 [ Info: 102 2.1e+02 2.3e-05 0.0e+00 8.2e-04 [ Info: 103 2.1e+02 2.2e-05 0.0e+00 8.2e-04 [ Info: 104 2.1e+02 2.5e-05 0.0e+00 8.5e-04 [ Info: 105 2.1e+02 2.3e-05 0.0e+00 8.4e-04 [ Info: 106 2.1e+02 2.5e-05 0.0e+00 9.5e-04 [ Info: 107 2.1e+02 2.4e-05 0.0e+00 8.5e-04 [ Info: 108 2.1e+02 2.6e-05 0.0e+00 1.1e-03 [ Info: 109 2.1e+02 3.1e-05 0.0e+00 9.9e-04 [ Info: 110 2.1e+02 2.9e-05 0.0e+00 1.1e-03 [ Info: 111 2.1e+02 2.5e-05 0.0e+00 9.2e-04 [ Info: 112 2.1e+02 3.3e-05 0.0e+00 1.0e-03 [ Info: 113 2.1e+02 3.2e-05 0.0e+00 9.8e-04 [ Info: 114 2.1e+02 3.3e-05 0.0e+00 1.0e-03 [ Info: 115 2.1e+02 3.4e-05 0.0e+00 1.0e-03 [ Info: 116 2.1e+02 3.6e-05 0.0e+00 1.1e-03 [ Info: 117 2.1e+02 3.6e-05 0.0e+00 1.1e-03 [ Info: 118 2.1e+02 3.8e-05 0.0e+00 1.1e-03 [ Info: 119 2.1e+02 3.9e-05 0.0e+00 1.1e-03 [ Info: 120 2.1e+02 4.0e-05 0.0e+00 1.1e-03 compliance = 210.96, vol = 0.5, gray = 0.378
1200-element Vector{Float64}:
0.9999999999999996
1.0000000000000002
1.0000000000000002
1.0
1.0
1.0000000000000002
1.0000000000000002
1.0000000000000002
1.0000000000000002
1.0
⋮
0.0
0.0
0.0
0.0
0.0
0.0
0.0
0.0
0.0
fig_plain = visualize(problem; static=true, topology=topo_plain)
display_app(fig_plain)Heaviside projection
ProjectedDensityFilterFun(solver; rmin, projection=...) applies the filter then the projection. The default projection is HeavisideProjectionFun(10.0).
heaviside_filter = ProjectedDensityFilterFun(solver; rmin=rmin, projection=HeavisideProjectionFun(8.0))
topo_h = solve_with(heaviside_filter)[ Info: iter obj Δobj violation kkt_residual [ Info: 0 1.2e+02 Inf 4.8e-01 7.0e-01 [ Info: 1 3.1e+03 3.0e+03 0.0e+00 2.8e+33 [ Info: 2 1.1e+05 1.1e+05 0.0e+00 4.5e+33 [ Info: 3 1.1e+05 0.0e+00 0.0e+00 1.0e+32 [ Info: 4 1.1e+05 0.0e+00 0.0e+00 6.1e+30 [ Info: 5 1.1e+05 0.0e+00 0.0e+00 1.3e+28 [ Info: 6 1.1e+05 0.0e+00 0.0e+00 1.3e+25 [ Info: 7 1.1e+05 0.0e+00 0.0e+00 1.3e+22 [ Info: 8 1.1e+05 0.0e+00 0.0e+00 1.3e+19 [ Info: 9 1.1e+05 0.0e+00 0.0e+00 1.3e+16 [ Info: 10 1.1e+05 0.0e+00 0.0e+00 6.3e-11 compliance = 114512.94, vol = 0.0, gray = 0.0
1200-element Vector{Float64}:
0.0
0.0
0.0
0.0
0.0
0.0
0.0
0.0
0.0
0.0
⋮
0.0
0.0
0.0
0.0
0.0
0.0
0.0
0.0
0.0
fig_h = visualize(problem; static=true, topology=topo_h)
display_app(fig_h)Sigmoid projection
A sigmoid projection is a smoother alternative; for the same β it produces a less aggressive threshold around the midpoint.
sigmoid_filter = ProjectedDensityFilterFun(solver; rmin=rmin, projection=SigmoidProjectionFun(8.0))
topo_s = solve_with(sigmoid_filter)[ Info: iter obj Δobj violation kkt_residual [ Info: 0 9.1e+02 Inf 0.0e+00 1.6e+02 [ Info: 1 1.0e+03 8.5e+01 0.0e+00 2.9e+02 [ Info: 2 6.1e+02 3.8e+02 0.0e+00 2.4e+02 [ Info: 3 4.4e+02 1.8e+02 0.0e+00 1.1e+02 [ Info: 4 3.3e+02 1.0e+02 0.0e+00 2.9e+01 [ Info: 5 3.0e+02 3.1e+01 0.0e+00 3.7e+00 [ Info: 6 2.9e+02 8.4e+00 0.0e+00 1.5e+00 [ Info: 7 2.9e+02 5.6e+00 0.0e+00 1.2e+00 [ Info: 8 2.8e+02 5.1e+00 0.0e+00 1.3e+00 [ Info: 9 2.8e+02 5.6e+00 0.0e+00 1.4e+00 [ Info: 10 2.7e+02 6.8e+00 0.0e+00 1.6e+00 [ Info: 11 2.6e+02 8.3e+00 0.0e+00 1.6e+00 [ Info: 12 2.5e+02 8.5e+00 0.0e+00 2.0e+00 [ Info: 13 2.4e+02 9.1e+00 0.0e+00 2.4e+00 [ Info: 14 2.3e+02 9.7e+00 0.0e+00 2.3e+00 [ Info: 15 2.2e+02 9.8e+00 0.0e+00 1.9e+00 [ Info: 16 2.2e+02 8.7e+00 0.0e+00 1.6e+00 [ Info: 17 2.1e+02 6.7e+00 0.0e+00 1.2e+00 [ Info: 18 2.0e+02 4.1e+00 0.0e+00 6.3e-01 [ Info: 19 2.0e+02 2.1e+00 0.0e+00 5.1e-01 [ Info: 20 2.0e+02 1.8e+00 0.0e+00 4.1e-01 [ Info: 21 2.0e+02 1.6e+00 0.0e+00 3.5e-01 [ Info: 22 2.0e+02 1.3e+00 0.0e+00 3.5e-01 [ Info: 23 2.0e+02 1.0e+00 0.0e+00 2.7e-01 [ Info: 24 2.0e+02 7.2e-01 0.0e+00 1.6e-01 [ Info: 25 2.0e+02 5.7e-01 0.0e+00 1.5e-01 [ Info: 26 2.0e+02 4.5e-01 0.0e+00 1.3e-01 [ Info: 27 1.9e+02 2.8e-01 0.0e+00 1.3e-01 [ Info: 28 1.9e+02 2.0e-01 0.0e+00 1.3e-01 [ Info: 29 1.9e+02 1.5e-01 0.0e+00 1.2e-01 [ Info: 30 1.9e+02 1.2e-01 0.0e+00 1.1e-01 [ Info: 31 1.9e+02 9.5e-02 0.0e+00 9.1e-02 [ Info: 32 1.9e+02 7.5e-02 0.0e+00 8.3e-02 [ Info: 33 1.9e+02 6.2e-02 0.0e+00 7.9e-02 [ Info: 34 1.9e+02 4.7e-02 0.0e+00 4.3e-02 [ Info: 35 1.9e+02 3.0e-02 0.0e+00 4.4e-02 [ Info: 36 1.9e+02 1.7e-02 0.0e+00 2.2e-02 [ Info: 37 1.9e+02 1.0e-02 0.0e+00 1.9e-02 [ Info: 38 1.9e+02 8.1e-03 0.0e+00 1.7e-02 [ Info: 39 1.9e+02 6.2e-03 0.0e+00 1.1e-02 [ Info: 40 1.9e+02 3.7e-03 0.0e+00 1.2e-02 [ Info: 41 1.9e+02 2.7e-03 0.0e+00 1.0e-02 [ Info: 42 1.9e+02 2.6e-03 0.0e+00 1.2e-02 [ Info: 43 1.9e+02 1.7e-03 0.0e+00 1.2e-02 [ Info: 44 1.9e+02 2.1e-03 0.0e+00 8.0e-03 [ Info: 45 1.9e+02 9.5e-04 0.0e+00 7.8e-03 [ Info: 46 1.9e+02 7.5e-04 0.0e+00 7.4e-03 [ Info: 47 1.9e+02 5.0e-04 0.0e+00 5.4e-03 [ Info: 48 1.9e+02 4.1e-04 0.0e+00 3.6e-03 [ Info: 49 1.9e+02 2.9e-04 0.0e+00 3.5e-03 [ Info: 50 1.9e+02 2.3e-04 0.0e+00 3.5e-03 [ Info: 51 1.9e+02 1.6e-04 0.0e+00 3.5e-03 [ Info: 52 1.9e+02 1.5e-04 0.0e+00 2.7e-03 [ Info: 53 1.9e+02 1.0e-04 0.0e+00 2.4e-03 [ Info: 54 1.9e+02 9.7e-05 0.0e+00 2.5e-03 [ Info: 55 1.9e+02 7.7e-05 0.0e+00 2.3e-03 [ Info: 56 1.9e+02 6.4e-05 0.0e+00 2.6e-03 [ Info: 57 1.9e+02 6.0e-05 0.0e+00 2.8e-03 [ Info: 58 1.9e+02 5.6e-05 0.0e+00 3.0e-03 [ Info: 59 1.9e+02 5.7e-05 0.0e+00 3.1e-03 [ Info: 60 1.9e+02 5.7e-05 0.0e+00 3.2e-03 [ Info: 61 1.9e+02 6.1e-05 0.0e+00 3.2e-03 [ Info: 62 1.9e+02 6.3e-05 0.0e+00 3.0e-03 [ Info: 63 1.9e+02 6.1e-05 0.0e+00 2.8e-03 [ Info: 64 1.9e+02 6.4e-05 0.0e+00 2.6e-03 [ Info: 65 1.9e+02 6.1e-05 0.0e+00 2.3e-03 [ Info: 66 1.9e+02 6.4e-05 0.0e+00 2.2e-03 [ Info: 67 1.9e+02 6.0e-05 0.0e+00 1.7e-03 [ Info: 68 1.9e+02 6.2e-05 0.0e+00 1.6e-03 [ Info: 69 1.9e+02 5.8e-05 0.0e+00 1.2e-03 [ Info: 70 1.9e+02 5.2e-05 0.0e+00 1.3e-03 [ Info: 71 1.9e+02 5.1e-05 0.0e+00 1.1e-03 [ Info: 72 1.9e+02 4.6e-05 0.0e+00 1.2e-03 [ Info: 73 1.9e+02 4.2e-05 0.0e+00 9.5e-04 [ Info: 74 1.9e+02 4.1e-05 0.0e+00 1.2e-03 [ Info: 75 1.9e+02 3.7e-05 0.0e+00 8.8e-04 [ Info: 76 1.9e+02 3.8e-05 0.0e+00 1.1e-03 [ Info: 77 1.9e+02 3.2e-05 0.0e+00 8.5e-04 [ Info: 78 1.9e+02 3.1e-05 0.0e+00 1.1e-03 [ Info: 79 1.9e+02 2.7e-05 0.0e+00 1.4e-03 [ Info: 80 1.9e+02 2.8e-05 0.0e+00 1.3e-03 [ Info: 81 1.9e+02 2.5e-05 0.0e+00 9.7e-04 [ Info: 82 1.9e+02 2.1e-05 0.0e+00 7.0e-04 [ Info: 83 1.9e+02 1.8e-05 0.0e+00 7.1e-04 [ Info: 84 1.9e+02 2.1e-05 0.0e+00 6.3e-04 [ Info: 85 1.9e+02 1.5e-05 0.0e+00 5.3e-04 [ Info: 86 1.9e+02 1.3e-05 0.0e+00 5.3e-04 [ Info: 87 1.9e+02 1.1e-05 0.0e+00 4.9e-04 [ Info: 88 1.9e+02 1.0e-05 0.0e+00 4.6e-04 [ Info: 89 1.9e+02 8.7e-06 0.0e+00 4.5e-04 [ Info: 90 1.9e+02 7.9e-06 0.0e+00 4.1e-04 [ Info: 91 1.9e+02 7.0e-06 0.0e+00 4.0e-04 [ Info: 92 1.9e+02 5.4e-06 0.0e+00 5.6e-04 [ Info: 93 1.9e+02 3.5e-06 0.0e+00 5.2e-04 [ Info: 94 1.9e+02 2.7e-06 0.0e+00 1.1e-03 [ Info: 95 1.9e+02 3.4e-06 8.9e-09 1.9e-03 [ Info: 96 1.9e+02 8.1e-07 1.2e-08 2.1e-03 [ Info: 97 1.9e+02 6.7e-06 2.8e-10 1.3e-03 [ Info: 98 1.9e+02 1.9e-06 0.0e+00 4.8e-04 [ Info: 99 1.9e+02 3.9e-06 0.0e+00 4.1e-04 [ Info: 100 1.9e+02 1.5e-06 0.0e+00 4.1e-04 [ Info: 101 1.9e+02 1.3e-06 0.0e+00 4.1e-04 [ Info: 102 1.9e+02 1.4e-06 0.0e+00 4.0e-04 [ Info: 103 1.9e+02 1.3e-06 0.0e+00 4.0e-04 [ Info: 104 1.9e+02 1.4e-06 0.0e+00 4.0e-04 [ Info: 105 1.9e+02 1.3e-06 0.0e+00 4.0e-04 [ Info: 106 1.9e+02 1.3e-06 0.0e+00 4.1e-04 [ Info: 107 1.9e+02 1.4e-06 0.0e+00 4.2e-04 [ Info: 108 1.9e+02 1.3e-06 0.0e+00 4.0e-04 [ Info: 109 1.9e+02 1.4e-06 0.0e+00 4.2e-04 [ Info: 110 1.9e+02 1.2e-06 0.0e+00 3.7e-04 [ Info: 111 1.9e+02 1.3e-06 0.0e+00 4.5e-04 [ Info: 112 1.9e+02 7.6e-07 0.0e+00 4.4e-04 [ Info: 113 1.9e+02 4.9e-07 0.0e+00 8.6e-04 [ Info: 114 1.9e+02 1.8e-07 8.3e-09 1.8e-03 [ Info: 115 1.9e+02 3.2e-06 1.7e-08 2.3e-03 [ Info: 116 1.9e+02 1.3e-06 1.1e-08 2.2e-03 [ Info: 117 1.9e+02 3.9e-06 0.0e+00 1.0e-03 [ Info: 118 1.9e+02 4.5e-06 0.0e+00 3.2e-04 [ Info: 119 1.9e+02 1.6e-06 0.0e+00 3.1e-04 [ Info: 120 1.9e+02 3.8e-07 0.0e+00 2.9e-04 compliance = 194.04, vol = 0.5, gray = 0.246
1200-element Vector{Float64}:
0.9890130573694068
0.9890130573694068
0.9890130573694068
0.9890130573694068
0.9890130573694068
0.9890130573694068
0.9890130573694068
0.9890130573694068
0.9890130573694068
0.9890130573694068
⋮
0.01098694263059318
0.01098694263059318
0.01098694263059318
0.01098694263059318
0.01098694263059318
0.01098694263059318
0.01098694263059318
0.01098694263059318
0.01098694263059318
fig_s = visualize(problem; static=true, topology=topo_s)
display_app(fig_s)Continuation on the projection parameter β
Starting with a mild projection (β = 2) and ramping it up sharpens the design gradually, avoiding the premature lock-in that a large fixed β can cause. The projection struct is mutable, so we update β in place between solves.
projection = HeavisideProjectionFun(2.0)
filt = ProjectedDensityFilterFun(solver; rmin=rmin, projection=projection)
obj = x -> comp(filt(PseudoDensities(x)))
constr = x -> volfrac(filt(PseudoDensities(x))) - V
model = Model(obj)
addvar!(model, zeros(N), ones(N))
add_ineq_constraint!(model, constr)
x = copy(x0)
for β in (2.0, 4.0, 8.0, 16.0)
projection.β = β
r = optimize(model, MMA87(), x;
options=MMAOptions(; maxiter=60, tol=Tolerance(; kkt=1e-3, f=1e-3)))
x = r.minimizer
topo = filt(PseudoDensities(x)).x
println("β=$β: compliance = $(round(obj(x), digits=2)), gray = $(round(grayness(topo), digits=3))")
end
topo_cont = filt(PseudoDensities(x)).x[ Info: iter obj Δobj violation kkt_residual [ Info: 0 3.3e+02 Inf 2.0e-01 1.6e+01 [ Info: 1 1.3e+04 1.2e+04 0.0e+00 6.1e+04 [ Info: 2 1.3e+03 1.2e+04 0.0e+00 7.9e+03 [ Info: 3 5.8e+02 6.9e+02 0.0e+00 2.0e+02 [ Info: 4 4.0e+02 1.8e+02 0.0e+00 3.6e+01 [ Info: 5 3.4e+02 5.9e+01 0.0e+00 1.2e+01 [ Info: 6 3.2e+02 2.4e+01 0.0e+00 4.9e+00 [ Info: 7 3.0e+02 1.2e+01 0.0e+00 3.0e+00 [ Info: 8 3.0e+02 8.7e+00 0.0e+00 2.5e+00 [ Info: 9 2.9e+02 7.1e+00 0.0e+00 2.1e+00 [ Info: 10 2.8e+02 6.2e+00 0.0e+00 1.9e+00 [ Info: 11 2.8e+02 5.8e+00 0.0e+00 1.8e+00 [ Info: 12 2.7e+02 6.0e+00 0.0e+00 1.9e+00 [ Info: 13 2.6e+02 6.8e+00 0.0e+00 2.2e+00 [ Info: 14 2.6e+02 6.4e+00 0.0e+00 2.1e+00 [ Info: 15 2.5e+02 6.3e+00 0.0e+00 2.1e+00 [ Info: 16 2.5e+02 5.4e+00 0.0e+00 2.1e+00 [ Info: 17 2.4e+02 5.6e+00 0.0e+00 2.1e+00 [ Info: 18 2.3e+02 6.4e+00 0.0e+00 1.9e+00 [ Info: 19 2.3e+02 5.7e+00 0.0e+00 1.5e+00 [ Info: 20 2.2e+02 4.3e+00 0.0e+00 1.2e+00 [ Info: 21 2.2e+02 2.6e+00 0.0e+00 1.1e+00 [ Info: 22 2.2e+02 1.6e+00 0.0e+00 9.2e-01 [ Info: 23 2.2e+02 1.6e+00 0.0e+00 9.2e-01 [ Info: 24 2.2e+02 1.5e+00 0.0e+00 9.2e-01 [ Info: 25 2.2e+02 1.2e+00 0.0e+00 9.0e-01 [ Info: 26 2.1e+02 9.9e-01 0.0e+00 5.4e-01 [ Info: 27 2.1e+02 1.1e+00 0.0e+00 8.7e-01 [ Info: 28 2.1e+02 8.4e-01 0.0e+00 8.8e-01 [ Info: 29 2.1e+02 5.3e-01 0.0e+00 9.2e-01 [ Info: 30 2.1e+02 2.3e-01 0.0e+00 2.5e-01 [ Info: 31 2.1e+02 1.2e-01 0.0e+00 2.7e-01 [ Info: 32 2.1e+02 7.8e-02 0.0e+00 2.8e-01 [ Info: 33 2.1e+02 7.5e-02 0.0e+00 3.0e-01 [ Info: 34 2.1e+02 6.9e-02 0.0e+00 3.2e-01 [ Info: 35 2.1e+02 7.8e-02 0.0e+00 3.5e-01 [ Info: 36 2.1e+02 8.2e-02 0.0e+00 1.9e-01 [ Info: 37 2.1e+02 7.5e-02 0.0e+00 2.1e-01 [ Info: 38 2.1e+02 6.1e-02 0.0e+00 2.2e-01 [ Info: 39 2.1e+02 4.6e-02 0.0e+00 1.5e-01 [ Info: 40 2.1e+02 3.6e-02 0.0e+00 8.9e-02 [ Info: 41 2.1e+02 2.9e-02 0.0e+00 8.5e-02 [ Info: 42 2.1e+02 3.0e-02 0.0e+00 8.9e-02 [ Info: 43 2.1e+02 3.3e-02 0.0e+00 6.4e-02 [ Info: 44 2.1e+02 2.9e-02 0.0e+00 5.3e-02 [ Info: 45 2.1e+02 2.6e-02 0.0e+00 4.1e-02 [ Info: 46 2.1e+02 2.2e-02 0.0e+00 3.0e-02 [ Info: 47 2.1e+02 1.9e-02 0.0e+00 2.4e-02 [ Info: 48 2.1e+02 1.5e-02 0.0e+00 2.4e-02 [ Info: 49 2.1e+02 1.4e-02 0.0e+00 2.5e-02 [ Info: 50 2.1e+02 1.2e-02 0.0e+00 2.0e-02 [ Info: 51 2.1e+02 7.6e-03 0.0e+00 1.8e-02 [ Info: 52 2.1e+02 6.1e-03 0.0e+00 1.6e-02 [ Info: 53 2.1e+02 5.5e-03 0.0e+00 1.4e-02 [ Info: 54 2.1e+02 6.0e-03 0.0e+00 1.4e-02 [ Info: 55 2.1e+02 7.0e-03 0.0e+00 1.8e-02 [ Info: 56 2.1e+02 8.8e-03 0.0e+00 2.3e-02 [ Info: 57 2.1e+02 9.4e-03 0.0e+00 3.2e-02 [ Info: 58 2.1e+02 1.3e-02 0.0e+00 4.4e-02 [ Info: 59 2.1e+02 2.0e-02 0.0e+00 5.6e-02 [ Info: 60 2.1e+02 3.9e-02 0.0e+00 7.5e-02 β=2.0: compliance = 211.11, gray = 0.401 [ Info: iter obj Δobj violation kkt_residual [ Info: 0 1.8e+02 Inf 6.7e-02 4.5e-01 [ Info: 1 2.8e+02 1.0e+02 0.0e+00 1.5e+33 [ Info: 2 6.5e+03 6.2e+03 0.0e+00 1.1e+34 [ Info: 3 1.1e+05 1.1e+05 0.0e+00 1.2e+34 [ Info: 4 1.1e+05 0.0e+00 0.0e+00 7.1e+33 [ Info: 5 1.1e+05 0.0e+00 0.0e+00 2.7e+33 [ Info: 6 1.1e+05 0.0e+00 0.0e+00 8.8e+32 [ Info: 7 1.1e+05 0.0e+00 0.0e+00 1.7e+32 [ Info: 8 1.1e+05 0.0e+00 0.0e+00 6.6e+30 [ Info: 9 1.1e+05 0.0e+00 0.0e+00 1.4e+28 [ Info: 10 1.1e+05 0.0e+00 0.0e+00 1.4e+25 [ Info: 11 1.1e+05 0.0e+00 0.0e+00 1.4e+22 [ Info: 12 1.1e+05 0.0e+00 0.0e+00 1.4e+19 [ Info: 13 1.1e+05 0.0e+00 0.0e+00 1.4e+16 [ Info: 14 1.1e+05 0.0e+00 0.0e+00 6.4e-11 β=4.0: compliance = 114512.94, gray = 0.0 [ Info: iter obj Δobj violation kkt_residual [ Info: 0 1.1e+05 Inf 0.0e+00 5.0e-01 [ Info: 1 1.1e+05 0.0e+00 0.0e+00 5.5e-10 β=8.0: compliance = 114512.94, gray = 0.0 [ Info: iter obj Δobj violation kkt_residual [ Info: 0 1.1e+05 Inf 0.0e+00 5.0e-01 [ Info: 1 1.1e+05 0.0e+00 0.0e+00 5.5e-10 β=16.0: compliance = 114512.94, gray = 0.0
1200-element Vector{Float64}:
0.0
0.0
0.0
0.0
0.0
0.0
0.0
0.0
0.0
0.0
⋮
0.0
0.0
0.0
0.0
0.0
0.0
0.0
0.0
0.0
fig_cont = visualize(problem; static=true, topology=topo_cont)
display_app(fig_cont)The reported grayness drops as β increases, confirming that the projection continuation drives the design toward a crisp 0/1 distribution.