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

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)

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
end

Plain 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   5.2e+01
[ Info:      1   6.2e+02   2.9e+02   0.0e+00   1.6e+02
[ Info:      2   4.3e+02   1.9e+02   0.0e+00   3.7e+01
[ Info:      3   3.6e+02   6.6e+01   0.0e+00   1.3e+01
[ Info:      4   3.3e+02   2.7e+01   0.0e+00   5.8e+00
[ Info:      5   3.2e+02   1.6e+01   0.0e+00   3.4e+00
[ Info:      6   3.1e+02   1.1e+01   0.0e+00   2.6e+00
[ Info:      7   3.0e+02   8.8e+00   0.0e+00   2.2e+00
[ Info:      8   2.9e+02   7.5e+00   0.0e+00   1.8e+00
[ Info:      9   2.8e+02   6.5e+00   0.0e+00   1.6e+00
[ Info:     10   2.8e+02   6.0e+00   0.0e+00   1.4e+00
[ Info:     11   2.7e+02   6.0e+00   0.0e+00   1.4e+00
[ Info:     12   2.6e+02   7.4e+00   0.0e+00   1.6e+00
[ Info:     13   2.5e+02   9.3e+00   0.0e+00   2.1e+00
[ Info:     14   2.4e+02   1.1e+01   0.0e+00   2.3e+00
[ Info:     15   2.3e+02   1.0e+01   0.0e+00   2.1e+00
[ Info:     16   2.2e+02   8.1e+00   0.0e+00   1.4e+00
[ Info:     17   2.2e+02   4.5e+00   0.0e+00   7.6e-01
[ Info:     18   2.2e+02   2.4e+00   0.0e+00   4.7e-01
[ Info:     19   2.2e+02   1.5e+00   0.0e+00   4.3e-01
[ Info:     20   2.1e+02   9.8e-01   0.0e+00   2.7e-01
[ Info:     21   2.1e+02   6.6e-01   0.0e+00   2.8e-01
[ Info:     22   2.1e+02   5.2e-01   0.0e+00   2.8e-01
[ Info:     23   2.1e+02   4.8e-01   0.0e+00   2.4e-01
[ Info:     24   2.1e+02   5.0e-01   0.0e+00   2.1e-01
[ Info:     25   2.1e+02   4.6e-01   0.0e+00   1.6e-01
[ Info:     26   2.1e+02   2.7e-01   0.0e+00   1.0e-01
[ Info:     27   2.1e+02   1.1e-01   0.0e+00   9.2e-02
[ Info:     28   2.1e+02   6.0e-02   0.0e+00   6.1e-02
[ Info:     29   2.1e+02   3.4e-02   0.0e+00   6.5e-02
[ Info:     30   2.1e+02   2.4e-02   0.0e+00   6.7e-02
[ Info:     31   2.1e+02   2.0e-02   0.0e+00   6.7e-02
[ Info:     32   2.1e+02   1.6e-02   0.0e+00   6.3e-02
[ Info:     33   2.1e+02   1.6e-02   0.0e+00   6.1e-02
[ Info:     34   2.1e+02   1.6e-02   0.0e+00   6.0e-02
[ Info:     35   2.1e+02   1.7e-02   0.0e+00   5.9e-02
[ Info:     36   2.1e+02   1.4e-02   0.0e+00   1.5e-02
[ Info:     37   2.1e+02   8.4e-03   0.0e+00   1.3e-02
[ Info:     38   2.1e+02   6.6e-03   0.0e+00   1.3e-02
[ Info:     39   2.1e+02   5.5e-03   0.0e+00   1.3e-02
[ Info:     40   2.1e+02   4.4e-03   0.0e+00   9.6e-03
[ Info:     41   2.1e+02   2.8e-03   0.0e+00   8.0e-03
[ Info:     42   2.1e+02   2.0e-03   0.0e+00   6.5e-03
[ Info:     43   2.1e+02   1.3e-03   0.0e+00   6.4e-03
[ Info:     44   2.1e+02   1.1e-03   0.0e+00   5.9e-03
[ Info:     45   2.1e+02   1.0e-03   0.0e+00   5.9e-03
[ Info:     46   2.1e+02   1.0e-03   0.0e+00   5.4e-03
[ Info:     47   2.1e+02   9.6e-04   0.0e+00   5.4e-03
[ Info:     48   2.1e+02   9.1e-04   0.0e+00   5.3e-03
[ Info:     49   2.1e+02   8.7e-04   0.0e+00   5.2e-03
[ Info:     50   2.1e+02   8.5e-04   0.0e+00   5.1e-03
[ Info:     51   2.1e+02   8.2e-04   0.0e+00   5.0e-03
[ Info:     52   2.1e+02   8.0e-04   0.0e+00   4.9e-03
[ Info:     53   2.1e+02   7.7e-04   0.0e+00   4.8e-03
[ Info:     54   2.1e+02   6.5e-04   0.0e+00   4.1e-03
[ Info:     55   2.1e+02   5.6e-04   0.0e+00   3.9e-03
[ Info:     56   2.1e+02   4.8e-04   0.0e+00   3.5e-03
[ Info:     57   2.1e+02   4.2e-04   0.0e+00   3.5e-03
[ Info:     58   2.1e+02   3.7e-04   0.0e+00   3.2e-03
[ Info:     59   2.1e+02   3.2e-04   0.0e+00   3.9e-03
[ Info:     60   2.1e+02   2.8e-04   0.0e+00   4.0e-03
[ Info:     61   2.1e+02   2.4e-04   0.0e+00   4.4e-03
[ Info:     62   2.1e+02   2.1e-04   0.0e+00   4.6e-03
[ Info:     63   2.1e+02   1.6e-04   0.0e+00   4.1e-03
[ Info:     64   2.1e+02   1.3e-04   0.0e+00   2.8e-03
[ Info:     65   2.1e+02   8.8e-05   0.0e+00   2.6e-03
[ Info:     66   2.1e+02   6.6e-05   0.0e+00   1.7e-03
[ Info:     67   2.1e+02   5.9e-05   0.0e+00   1.7e-03
[ Info:     68   2.1e+02   5.9e-05   0.0e+00   1.7e-03
[ Info:     69   2.1e+02   6.0e-05   0.0e+00   1.7e-03
[ Info:     70   2.1e+02   6.0e-05   0.0e+00   1.7e-03
[ Info:     71   2.1e+02   6.0e-05   0.0e+00   1.7e-03
[ Info:     72   2.1e+02   5.9e-05   0.0e+00   1.7e-03
[ Info:     73   2.1e+02   5.8e-05   0.0e+00   1.7e-03
[ Info:     74   2.1e+02   5.6e-05   0.0e+00   1.6e-03
[ Info:     75   2.1e+02   5.5e-05   0.0e+00   1.6e-03
[ Info:     76   2.1e+02   5.3e-05   0.0e+00   1.6e-03
[ Info:     77   2.1e+02   5.1e-05   0.0e+00   1.6e-03
[ Info:     78   2.1e+02   4.5e-05   0.0e+00   1.4e-03
[ Info:     79   2.1e+02   4.1e-05   0.0e+00   1.5e-03
[ Info:     80   2.1e+02   3.7e-05   0.0e+00   1.4e-03
[ Info:     81   2.1e+02   3.4e-05   0.0e+00   1.6e-03
[ Info:     82   2.1e+02   3.1e-05   0.0e+00   1.3e-03
[ Info:     83   2.1e+02   2.9e-05   0.0e+00   1.6e-03
[ Info:     84   2.1e+02   2.7e-05   0.0e+00   1.2e-03
[ Info:     85   2.1e+02   2.5e-05   0.0e+00   1.8e-03
[ Info:     86   2.1e+02   2.3e-05   0.0e+00   1.4e-03
[ Info:     87   2.1e+02   2.2e-05   0.0e+00   2.0e-03
[ Info:     88   2.1e+02   2.1e-05   0.0e+00   1.5e-03
[ Info:     89   2.1e+02   2.0e-05   0.0e+00   2.0e-03
[ Info:     90   2.1e+02   2.0e-05   0.0e+00   1.4e-03
[ Info:     91   2.1e+02   1.9e-05   0.0e+00   1.7e-03
[ Info:     92   2.1e+02   1.5e-05   0.0e+00   9.5e-04
[ Info:     93   2.1e+02   7.6e-06   0.0e+00   1.0e-03
[ Info:     94   2.1e+02   3.6e-06   0.0e+00   1.0e-03
[ Info:     95   2.1e+02   3.2e-06   0.0e+00   9.9e-04
[ Info:     96   2.1e+02   3.1e-06   0.0e+00   9.3e-04
[ Info:     97   2.1e+02   3.2e-06   0.0e+00   8.6e-04
[ Info:     98   2.1e+02   3.2e-06   0.0e+00   7.8e-04
[ Info:     99   2.1e+02   3.2e-06   0.0e+00   7.1e-04
[ Info:    100   2.1e+02   3.2e-06   0.0e+00   6.3e-04
[ Info:    101   2.1e+02   3.2e-06   0.0e+00   5.6e-04
[ Info:    102   2.1e+02   3.2e-06   0.0e+00   4.9e-04
[ Info:    103   2.1e+02   3.1e-06   0.0e+00   4.3e-04
[ Info:    104   2.1e+02   3.0e-06   0.0e+00   3.8e-04
[ Info:    105   2.1e+02   2.7e-06   0.0e+00   3.6e-04
[ Info:    106   2.1e+02   2.4e-06   0.0e+00   3.2e-04
[ Info:    107   2.1e+02   2.1e-06   0.0e+00   3.0e-04
[ Info:    108   2.1e+02   1.8e-06   0.0e+00   2.6e-04
[ Info:    109   2.1e+02   1.6e-06   0.0e+00   2.5e-04
[ Info:    110   2.1e+02   1.5e-06   0.0e+00   2.2e-04
[ Info:    111   2.1e+02   1.3e-06   0.0e+00   2.0e-04
[ Info:    112   2.1e+02   1.2e-06   0.0e+00   1.8e-04
[ Info:    113   2.1e+02   1.1e-06   0.0e+00   1.7e-04
[ Info:    114   2.1e+02   1.0e-06   0.0e+00   1.7e-04
[ Info:    115   2.1e+02   9.4e-07   0.0e+00   1.6e-04
[ Info:    116   2.1e+02   8.7e-07   0.0e+00   1.6e-04
[ Info:    117   2.1e+02   8.1e-07   0.0e+00   1.6e-04
[ Info:    118   2.1e+02   7.6e-07   0.0e+00   1.5e-04
[ Info:    119   2.1e+02   7.1e-07   0.0e+00   1.5e-04
[ Info:    120   2.1e+02   6.7e-07   0.0e+00   1.4e-04
compliance = 211.73, vol = 0.5, gray = 0.381
1200-element Vector{Float64}:
 1.0
 0.9999999999999999
 0.9999999999999999
 1.0
 0.9999999999999998
 0.9999999999999998
 0.9999999999999996
 0.9999999999999998
 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)
undeformed mesh
load arrows
support arrows
Figure 1: Plain density filter: smooth design with visible gray boundary layer

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   5.2e-01
[ Info:      1   3.1e+03   3.0e+03   0.0e+00   2.8e+33
[ Info:      2   7.6e+03   4.5e+03   0.0e+00   4.8e+03
[ Info:      3   4.9e+03   2.7e+03   0.0e+00   3.1e+03
[ Info:      4   2.2e+03   2.7e+03   0.0e+00   1.1e+03
[ Info:      5   1.2e+03   1.1e+03   0.0e+00   9.3e+02
[ Info:      6   1.1e+03   9.9e+01   0.0e+00   6.3e+02
[ Info:      7   1.2e+03   1.3e+02   0.0e+00   1.2e+03
[ Info:      8   1.0e+03   2.0e+02   0.0e+00   1.3e+03
[ Info:      9   5.6e+02   4.6e+02   0.0e+00   2.7e+02
[ Info:     10   4.1e+02   1.5e+02   0.0e+00   3.8e+01
[ Info:     11   3.5e+02   5.8e+01   0.0e+00   1.6e+01
[ Info:     12   3.3e+02   2.7e+01   0.0e+00   7.0e+00
[ Info:     13   3.1e+02   1.4e+01   0.0e+00   5.6e+00
[ Info:     14   3.0e+02   9.4e+00   0.0e+00   4.9e+00
[ Info:     15   3.0e+02   6.9e+00   0.0e+00   2.6e+00
[ Info:     16   2.9e+02   5.8e+00   0.0e+00   2.8e+00
[ Info:     17   2.9e+02   5.4e+00   0.0e+00   3.9e+00
[ Info:     18   2.8e+02   7.3e+00   0.0e+00   3.7e+00
[ Info:     19   2.7e+02   6.8e+00   0.0e+00   5.0e+00
[ Info:     20   2.7e+02   9.9e-01   0.0e+00   7.0e+00
[ Info:     21   2.6e+02   7.5e+00   0.0e+00   3.3e+00
[ Info:     22   2.6e+02   4.7e+00   0.0e+00   1.4e+00
[ Info:     23   2.6e+02   2.8e+00   0.0e+00   1.2e+00
[ Info:     24   2.5e+02   2.2e+00   0.0e+00   1.3e+00
[ Info:     25   2.5e+02   1.7e+00   0.0e+00   1.3e+00
[ Info:     26   2.5e+02   1.4e+00   0.0e+00   8.2e-01
[ Info:     27   2.5e+02   1.1e+00   0.0e+00   9.3e-01
[ Info:     28   2.5e+02   1.1e+00   0.0e+00   9.0e-01
[ Info:     29   2.5e+02   1.1e+00   0.0e+00   1.2e+00
[ Info:     30   2.5e+02   1.2e+00   0.0e+00   8.2e-01
[ Info:     31   2.5e+02   9.0e-01   0.0e+00   6.4e-01
[ Info:     32   2.4e+02   7.5e-01   0.0e+00   6.8e-01
[ Info:     33   2.4e+02   2.1e-01   0.0e+00   1.4e+00
[ Info:     34   2.5e+02   2.7e-01   0.0e+00   1.8e+00
[ Info:     35   2.4e+02   1.1e+00   0.0e+00   1.4e+00
[ Info:     36   2.4e+02   8.2e-01   0.0e+00   1.7e+00
[ Info:     37   2.4e+02   8.1e-01   0.0e+00   1.1e+00
[ Info:     38   2.4e+02   1.1e+00   0.0e+00   6.7e-01
[ Info:     39   2.4e+02   7.8e-01   0.0e+00   5.2e-01
[ Info:     40   2.4e+02   7.0e-01   0.0e+00   3.6e-01
[ Info:     41   2.4e+02   5.0e-01   0.0e+00   4.0e-01
[ Info:     42   2.4e+02   3.3e-01   0.0e+00   3.7e-01
[ Info:     43   2.4e+02   2.9e-01   0.0e+00   4.2e-01
[ Info:     44   2.4e+02   3.6e-01   0.0e+00   4.4e-01
[ Info:     45   2.4e+02   2.9e-01   0.0e+00   4.7e-01
[ Info:     46   2.4e+02   2.5e-01   0.0e+00   4.8e-01
[ Info:     47   2.4e+02   2.3e-01   0.0e+00   4.8e-01
[ Info:     48   2.4e+02   2.3e-01   0.0e+00   4.8e-01
[ Info:     49   2.4e+02   2.1e-01   0.0e+00   4.6e-01
[ Info:     50   2.4e+02   2.4e-01   0.0e+00   5.0e-01
[ Info:     51   2.4e+02   1.7e-01   0.0e+00   4.6e-01
[ Info:     52   2.4e+02   1.3e-01   0.0e+00   5.3e-01
[ Info:     53   2.4e+02   1.1e-01   0.0e+00   4.8e-01
[ Info:     54   2.4e+02   4.8e-02   0.0e+00   8.3e-01
[ Info:     55   2.4e+02   6.7e-01   0.0e+00   8.2e-01
[ Info:     56   2.4e+02   2.1e-01   0.0e+00   9.0e-01
[ Info:     57   2.4e+02   3.4e-01   0.0e+00   6.9e-01
[ Info:     58   2.4e+02   5.3e-01   0.0e+00   2.6e-01
[ Info:     59   2.4e+02   2.9e-01   0.0e+00   2.0e-01
[ Info:     60   2.4e+02   1.3e-01   0.0e+00   1.5e-01
[ Info:     61   2.4e+02   9.8e-02   0.0e+00   1.9e-01
[ Info:     62   2.4e+02   1.2e-01   0.0e+00   1.6e-01
[ Info:     63   2.4e+02   1.2e-01   0.0e+00   2.5e-01
[ Info:     64   2.4e+02   1.4e-01   0.0e+00   2.4e-01
[ Info:     65   2.3e+02   7.8e-02   0.0e+00   4.9e-01
[ Info:     66   2.3e+02   1.2e-01   0.0e+00   3.5e-01
[ Info:     67   2.3e+02   2.0e-01   0.0e+00   3.4e-01
[ Info:     68   2.3e+02   2.0e-01   0.0e+00   2.0e-01
[ Info:     69   2.3e+02   1.4e-01   0.0e+00   2.6e-01
[ Info:     70   2.3e+02   1.3e-01   0.0e+00   2.2e-01
[ Info:     71   2.3e+02   1.4e-01   0.0e+00   2.4e-01
[ Info:     72   2.3e+02   1.7e-01   0.0e+00   2.7e-01
[ Info:     73   2.3e+02   1.6e-01   0.0e+00   2.6e-01
[ Info:     74   2.3e+02   1.4e-01   0.0e+00   2.0e-01
[ Info:     75   2.3e+02   1.1e-01   0.0e+00   2.0e-01
[ Info:     76   2.3e+02   1.0e-01   0.0e+00   1.9e-01
[ Info:     77   2.3e+02   8.9e-02   0.0e+00   1.8e-01
[ Info:     78   2.3e+02   8.3e-02   0.0e+00   1.9e-01
[ Info:     79   2.3e+02   8.4e-02   0.0e+00   2.0e-01
[ Info:     80   2.3e+02   7.9e-02   0.0e+00   2.0e-01
[ Info:     81   2.3e+02   8.2e-02   0.0e+00   2.4e-01
[ Info:     82   2.3e+02   8.2e-02   0.0e+00   2.3e-01
[ Info:     83   2.3e+02   8.1e-02   0.0e+00   2.2e-01
[ Info:     84   2.3e+02   7.9e-02   0.0e+00   2.4e-01
[ Info:     85   2.3e+02   1.1e-02   0.0e+00   2.4e-01
[ Info:     86   2.3e+02   6.4e-02   0.0e+00   2.6e-01
[ Info:     87   2.3e+02   1.1e-01   0.0e+00   2.8e-01
[ Info:     88   2.3e+02   1.2e-01   0.0e+00   2.8e-01
[ Info:     89   2.3e+02   7.7e-02   0.0e+00   2.8e-01
[ Info:     90   2.3e+02   8.5e-03   0.0e+00   9.3e-01
[ Info:     91   2.3e+02   8.7e-01   0.0e+00   8.8e-01
[ Info:     92   2.3e+02   7.5e-02   0.0e+00   2.9e+00
[ Info:     93   2.4e+02   2.2e+00   0.0e+00   2.5e+00
[ Info:     94   2.3e+02   1.8e+00   0.0e+00   1.7e+00
[ Info:     95   2.3e+02   1.0e+00   0.0e+00   1.3e+00
[ Info:     96   2.3e+02   4.9e-01   0.0e+00   4.3e-01
[ Info:     97   2.3e+02   2.1e-01   0.0e+00   2.5e-01
[ Info:     98   2.3e+02   4.0e-02   0.0e+00   2.6e-01
[ Info:     99   2.3e+02   3.9e-02   0.0e+00   2.4e-01
[ Info:    100   2.3e+02   4.3e-02   0.0e+00   2.4e-01
[ Info:    101   2.3e+02   4.0e-02   0.0e+00   2.1e-01
[ Info:    102   2.3e+02   4.2e-02   0.0e+00   2.1e-01
[ Info:    103   2.3e+02   4.7e-02   0.0e+00   2.1e-01
[ Info:    104   2.3e+02   6.0e-02   0.0e+00   2.2e-01
[ Info:    105   2.3e+02   8.1e-02   0.0e+00   2.4e-01
[ Info:    106   2.3e+02   9.4e-02   0.0e+00   2.4e-01
[ Info:    107   2.3e+02   9.8e-02   0.0e+00   2.5e-01
[ Info:    108   2.3e+02   1.1e-01   0.0e+00   2.4e-01
[ Info:    109   2.3e+02   1.0e-01   0.0e+00   2.7e-01
[ Info:    110   2.3e+02   1.1e-01   0.0e+00   2.8e-01
[ Info:    111   2.3e+02   1.1e-01   0.0e+00   2.3e-01
[ Info:    112   2.3e+02   1.2e-01   0.0e+00   2.8e-01
[ Info:    113   2.3e+02   1.5e-01   0.0e+00   2.6e-01
[ Info:    114   2.3e+02   2.1e-01   0.0e+00   2.1e-01
[ Info:    115   2.3e+02   1.5e-01   0.0e+00   4.1e-01
[ Info:    116   2.3e+02   1.3e-01   0.0e+00   5.2e-01
[ Info:    117   2.3e+02   6.8e-02   0.0e+00   1.2e+00
[ Info:    118   2.3e+02   8.1e-01   0.0e+00   1.4e+00
[ Info:    119   2.3e+02   1.9e-01   0.0e+00   2.2e+00
[ Info:    120   2.3e+02   7.7e-03   0.0e+00   1.5e+00
compliance = 231.48, vol = 0.498, gray = 0.372
1200-element Vector{Float64}:
 0.9992084080936713
 0.999407608979825
 0.9994985577449796
 0.9994618245671884
 0.9995028265632926
 0.9995845995323177
 0.999648371801894
 0.9996956371351371
 0.9997163428441226
 0.9997228887877109
 ⋮
 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)
undeformed mesh
load arrows
support arrows
Figure 2: Heaviside projection: near-binary design with far fewer gray elements

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.2e+02
[ Info:      1   1.0e+03   8.8e+01   0.0e+00   2.9e+02
[ Info:      2   6.2e+02   3.8e+02   0.0e+00   2.4e+02
[ Info:      3   5.7e+02   4.5e+01   0.0e+00   1.1e+02
[ Info:      4   3.8e+02   1.9e+02   0.0e+00   8.1e+01
[ Info:      5   3.1e+02   7.5e+01   0.0e+00   1.5e+01
[ Info:      6   2.9e+02   1.8e+01   0.0e+00   3.1e+00
[ Info:      7   2.8e+02   7.1e+00   0.0e+00   1.4e+00
[ Info:      8   2.8e+02   5.1e+00   0.0e+00   1.2e+00
[ Info:      9   2.7e+02   4.9e+00   0.0e+00   1.2e+00
[ Info:     10   2.7e+02   5.3e+00   0.0e+00   1.3e+00
[ Info:     11   2.6e+02   6.1e+00   0.0e+00   1.5e+00
[ Info:     12   2.6e+02   6.9e+00   0.0e+00   1.6e+00
[ Info:     13   2.5e+02   7.5e+00   0.0e+00   1.8e+00
[ Info:     14   2.4e+02   8.2e+00   0.0e+00   1.8e+00
[ Info:     15   2.3e+02   8.8e+00   0.0e+00   1.7e+00
[ Info:     16   2.2e+02   9.3e+00   0.0e+00   1.6e+00
[ Info:     17   2.1e+02   9.2e+00   0.0e+00   1.5e+00
[ Info:     18   2.1e+02   5.3e+00   0.0e+00   1.2e+00
[ Info:     19   2.0e+02   3.2e+00   0.0e+00   7.6e-01
[ Info:     20   2.0e+02   2.1e+00   0.0e+00   4.9e-01
[ Info:     21   2.0e+02   1.6e+00   0.0e+00   3.6e-01
[ Info:     22   2.0e+02   1.4e+00   0.0e+00   3.1e-01
[ Info:     23   2.0e+02   1.4e+00   0.0e+00   3.7e-01
[ Info:     24   2.0e+02   1.2e+00   0.0e+00   3.2e-01
[ Info:     25   2.0e+02   8.4e-01   0.0e+00   2.0e-01
[ Info:     26   2.0e+02   5.1e-01   0.0e+00   1.8e-01
[ Info:     27   2.0e+02   3.9e-01   0.0e+00   1.9e-01
[ Info:     28   2.0e+02   2.8e-01   0.0e+00   1.4e-01
[ Info:     29   1.9e+02   2.2e-01   0.0e+00   1.4e-01
[ Info:     30   1.9e+02   1.9e-01   0.0e+00   1.3e-01
[ Info:     31   1.9e+02   1.2e-01   0.0e+00   1.3e-01
[ Info:     32   1.9e+02   7.1e-02   0.0e+00   7.5e-02
[ Info:     33   1.9e+02   4.2e-02   0.0e+00   6.6e-02
[ Info:     34   1.9e+02   2.9e-02   0.0e+00   6.0e-02
[ Info:     35   1.9e+02   2.0e-02   0.0e+00   6.8e-02
[ Info:     36   1.9e+02   1.5e-02   0.0e+00   6.9e-02
[ Info:     37   1.9e+02   9.1e-03   0.0e+00   7.1e-02
[ Info:     38   1.9e+02   5.3e-03   0.0e+00   6.9e-02
[ Info:     39   1.9e+02   4.4e-03   0.0e+00   7.0e-02
[ Info:     40   1.9e+02   3.9e-03   0.0e+00   7.0e-02
[ Info:     41   1.9e+02   4.0e-03   0.0e+00   7.1e-02
[ Info:     42   1.9e+02   3.4e-03   0.0e+00   6.4e-02
[ Info:     43   1.9e+02   3.6e-03   0.0e+00   6.8e-02
[ Info:     44   1.9e+02   3.4e-03   0.0e+00   6.5e-02
[ Info:     45   1.9e+02   3.7e-03   0.0e+00   7.0e-02
[ Info:     46   1.9e+02   3.9e-03   0.0e+00   6.6e-02
[ Info:     47   1.9e+02   3.1e-03   0.0e+00   7.1e-02
[ Info:     48   1.9e+02   3.8e-03   0.0e+00   6.9e-02
[ Info:     49   1.9e+02   3.9e-03   0.0e+00   7.1e-02
[ Info:     50   1.9e+02   5.1e-03   0.0e+00   7.0e-02
[ Info:     51   1.9e+02   5.7e-03   0.0e+00   7.0e-02
[ Info:     52   1.9e+02   7.2e-03   0.0e+00   6.8e-02
[ Info:     53   1.9e+02   3.4e-03   0.0e+00   7.9e-03
[ Info:     54   1.9e+02   1.5e-03   0.0e+00   7.5e-03
[ Info:     55   1.9e+02   7.6e-04   0.0e+00   6.7e-03
[ Info:     56   1.9e+02   1.0e-03   0.0e+00   7.1e-03
[ Info:     57   1.9e+02   7.6e-04   0.0e+00   6.2e-03
[ Info:     58   1.9e+02   9.3e-04   0.0e+00   4.6e-03
[ Info:     59   1.9e+02   4.4e-04   0.0e+00   2.5e-03
[ Info:     60   1.9e+02   3.5e-04   0.0e+00   2.7e-03
[ Info:     61   1.9e+02   3.9e-04   0.0e+00   2.9e-03
[ Info:     62   1.9e+02   5.4e-04   0.0e+00   1.4e-03
[ Info:     63   1.9e+02   9.2e-05   0.0e+00   1.4e-03
[ Info:     64   1.9e+02   2.8e-05   0.0e+00   1.1e-03
[ Info:     65   1.9e+02   2.6e-05   0.0e+00   9.0e-04
[ Info:     66   1.9e+02   1.9e-05   0.0e+00   6.8e-04
[ Info:     67   1.9e+02   1.6e-05   0.0e+00   7.1e-04
[ Info:     68   1.9e+02   1.3e-05   0.0e+00   6.8e-04
[ Info:     69   1.9e+02   1.2e-05   0.0e+00   6.7e-04
[ Info:     70   1.9e+02   9.2e-06   0.0e+00   5.4e-04
[ Info:     71   1.9e+02   6.9e-06   0.0e+00   9.8e-04
[ Info:     72   1.9e+02   4.9e-06   0.0e+00   1.4e-03
[ Info:     73   1.9e+02   7.1e-06   0.0e+00   1.6e-03
[ Info:     74   1.9e+02   1.1e-05   0.0e+00   5.1e-04
[ Info:     75   1.9e+02   7.2e-06   0.0e+00   3.4e-04
[ Info:     76   1.9e+02   7.5e-06   0.0e+00   3.5e-04
[ Info:     77   1.9e+02   5.2e-06   0.0e+00   3.3e-04
[ Info:     78   1.9e+02   6.0e-06   0.0e+00   3.4e-04
[ Info:     79   1.9e+02   5.0e-06   0.0e+00   3.3e-04
[ Info:     80   1.9e+02   5.9e-06   0.0e+00   3.9e-04
[ Info:     81   1.9e+02   4.5e-06   0.0e+00   3.6e-04
[ Info:     82   1.9e+02   5.2e-06   0.0e+00   5.0e-04
[ Info:     83   1.9e+02   3.4e-06   0.0e+00   6.3e-04
[ Info:     84   1.9e+02   5.7e-06   0.0e+00   4.7e-04
[ Info:     85   1.9e+02   5.6e-06   0.0e+00   3.7e-04
[ Info:     86   1.9e+02   5.4e-06   0.0e+00   3.4e-04
[ Info:     87   1.9e+02   3.6e-06   0.0e+00   3.4e-04
[ Info:     88   1.9e+02   4.0e-06   0.0e+00   3.4e-04
[ Info:     89   1.9e+02   3.6e-06   0.0e+00   3.2e-04
[ Info:     90   1.9e+02   3.7e-06   0.0e+00   3.8e-04
[ Info:     91   1.9e+02   4.1e-06   0.0e+00   3.6e-04
[ Info:     92   1.9e+02   4.5e-06   0.0e+00   3.0e-04
[ Info:     93   1.9e+02   4.8e-06   0.0e+00   3.2e-04
[ Info:     94   1.9e+02   4.7e-06   0.0e+00   3.4e-04
[ Info:     95   1.9e+02   4.9e-06   0.0e+00   3.5e-04
[ Info:     96   1.9e+02   4.8e-06   0.0e+00   3.6e-04
[ Info:     97   1.9e+02   4.7e-06   0.0e+00   3.6e-04
[ Info:     98   1.9e+02   4.5e-06   0.0e+00   3.9e-04
[ Info:     99   1.9e+02   4.1e-06   0.0e+00   5.3e-04
[ Info:    100   1.9e+02   5.0e-06   0.0e+00   4.3e-04
[ Info:    101   1.9e+02   5.1e-06   0.0e+00   3.5e-04
[ Info:    102   1.9e+02   4.7e-06   0.0e+00   3.3e-04
[ Info:    103   1.9e+02   4.0e-06   0.0e+00   3.6e-04
[ Info:    104   1.9e+02   3.9e-06   0.0e+00   3.7e-04
[ Info:    105   1.9e+02   4.4e-06   0.0e+00   3.6e-04
[ Info:    106   1.9e+02   4.3e-06   0.0e+00   3.4e-04
[ Info:    107   1.9e+02   5.1e-06   0.0e+00   3.4e-04
[ Info:    108   1.9e+02   4.8e-06   0.0e+00   3.6e-04
[ Info:    109   1.9e+02   5.3e-06   0.0e+00   3.6e-04
[ Info:    110   1.9e+02   5.4e-06   0.0e+00   3.8e-04
[ Info:    111   1.9e+02   5.9e-06   0.0e+00   4.0e-04
[ Info:    112   1.9e+02   6.1e-06   0.0e+00   4.1e-04
[ Info:    113   1.9e+02   6.4e-06   0.0e+00   4.3e-04
[ Info:    114   1.9e+02   6.6e-06   0.0e+00   4.4e-04
[ Info:    115   1.9e+02   7.0e-06   0.0e+00   4.7e-04
[ Info:    116   1.9e+02   7.0e-06   0.0e+00   4.7e-04
[ Info:    117   1.9e+02   7.1e-06   0.0e+00   5.1e-04
[ Info:    118   1.9e+02   5.9e-06   0.0e+00   6.4e-04
[ Info:    119   1.9e+02   7.6e-06   0.0e+00   5.8e-04
[ Info:    120   1.9e+02   9.3e-06   0.0e+00   5.1e-04
compliance = 194.4, vol = 0.5, gray = 0.24
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)
undeformed mesh
load arrows
support arrows
Figure 3: Sigmoid projection: similar topology with a smoother 0/1 transition

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.2e+01
[ Info:      1   1.3e+04   1.3e+04   0.0e+00   6.1e+04
[ Info:      2   1.3e+03   1.2e+04   0.0e+00   7.9e+03
[ Info:      3   5.5e+02   7.2e+02   0.0e+00   2.5e+02
[ Info:      4   3.8e+02   1.7e+02   0.0e+00   4.4e+01
[ Info:      5   3.2e+02   5.6e+01   0.0e+00   1.1e+01
[ Info:      6   3.1e+02   1.9e+01   0.0e+00   4.4e+00
[ Info:      7   2.9e+02   1.1e+01   0.0e+00   2.7e+00
[ Info:      8   2.9e+02   7.5e+00   0.0e+00   2.3e+00
[ Info:      9   2.8e+02   6.1e+00   0.0e+00   1.8e+00
[ Info:     10   2.8e+02   5.8e+00   0.0e+00   1.9e+00
[ Info:     11   2.7e+02   5.8e+00   0.0e+00   1.8e+00
[ Info:     12   2.6e+02   5.8e+00   0.0e+00   1.8e+00
[ Info:     13   2.6e+02   5.4e+00   0.0e+00   1.6e+00
[ Info:     14   2.5e+02   5.5e+00   0.0e+00   1.7e+00
[ Info:     15   2.5e+02   5.4e+00   0.0e+00   1.6e+00
[ Info:     16   2.4e+02   5.1e+00   0.0e+00   1.5e+00
[ Info:     17   2.4e+02   5.7e+00   0.0e+00   1.7e+00
[ Info:     18   2.3e+02   6.8e+00   0.0e+00   2.1e+00
[ Info:     19   2.2e+02   7.4e+00   0.0e+00   2.0e+00
[ Info:     20   2.2e+02   5.4e+00   0.0e+00   1.3e+00
[ Info:     21   2.1e+02   2.7e+00   0.0e+00   8.6e-01
[ Info:     22   2.1e+02   1.2e+00   0.0e+00   3.3e-01
[ Info:     23   2.1e+02   5.5e-01   0.0e+00   2.2e-01
[ Info:     24   2.1e+02   3.3e-01   0.0e+00   2.2e-01
[ Info:     25   2.1e+02   2.6e-01   0.0e+00   2.1e-01
[ Info:     26   2.1e+02   1.7e-01   0.0e+00   2.0e-01
[ Info:     27   2.1e+02   9.2e-02   0.0e+00   2.1e-01
[ Info:     28   2.1e+02   5.8e-02   0.0e+00   8.5e-02
[ Info:     29   2.1e+02   4.0e-02   0.0e+00   8.2e-02
[ Info:     30   2.1e+02   2.7e-02   0.0e+00   7.5e-02
[ Info:     31   2.1e+02   1.8e-02   0.0e+00   6.5e-02
[ Info:     32   2.1e+02   1.3e-02   0.0e+00   4.0e-02
[ Info:     33   2.1e+02   8.5e-03   0.0e+00   4.0e-02
[ Info:     34   2.1e+02   7.7e-03   0.0e+00   3.9e-02
[ Info:     35   2.1e+02   6.7e-03   0.0e+00   4.0e-02
[ Info:     36   2.1e+02   5.7e-03   0.0e+00   1.3e-02
[ Info:     37   2.1e+02   3.4e-03   0.0e+00   1.2e-02
[ Info:     38   2.1e+02   2.4e-03   0.0e+00   1.2e-02
[ Info:     39   2.1e+02   2.1e-03   0.0e+00   1.1e-02
[ Info:     40   2.1e+02   2.1e-03   0.0e+00   1.1e-02
[ Info:     41   2.1e+02   2.1e-03   0.0e+00   9.3e-03
[ Info:     42   2.1e+02   1.8e-03   0.0e+00   6.2e-03
[ Info:     43   2.1e+02   1.2e-03   0.0e+00   5.3e-03
[ Info:     44   2.1e+02   9.6e-04   0.0e+00   4.4e-03
[ Info:     45   2.1e+02   7.6e-04   0.0e+00   3.4e-03
[ Info:     46   2.1e+02   6.2e-04   0.0e+00   4.0e-03
[ Info:     47   2.1e+02   5.6e-04   0.0e+00   4.4e-03
[ Info:     48   2.1e+02   5.2e-04   0.0e+00   4.3e-03
[ Info:     49   2.1e+02   4.6e-04   0.0e+00   3.7e-03
[ Info:     50   2.1e+02   4.1e-04   0.0e+00   3.2e-03
[ Info:     51   2.1e+02   3.6e-04   0.0e+00   3.0e-03
[ Info:     52   2.1e+02   3.3e-04   0.0e+00   2.8e-03
[ Info:     53   2.1e+02   3.2e-04   0.0e+00   2.7e-03
[ Info:     54   2.1e+02   3.3e-04   0.0e+00   2.6e-03
[ Info:     55   2.1e+02   3.5e-04   0.0e+00   2.9e-03
[ Info:     56   2.1e+02   3.7e-04   0.0e+00   3.1e-03
[ Info:     57   2.1e+02   4.0e-04   0.0e+00   3.6e-03
[ Info:     58   2.1e+02   4.5e-04   0.0e+00   4.1e-03
[ Info:     59   2.1e+02   5.2e-04   0.0e+00   4.6e-03
[ Info:     60   2.1e+02   6.4e-04   0.0e+00   5.4e-03
β=2.0: compliance = 211.38, gray = 0.388
[ 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.4e+33
[ Info:      2   2.4e+02   4.6e+01   0.0e+00   1.1e+01
[ Info:      3   2.2e+02   1.7e+01   0.0e+00   3.2e+00
[ Info:      4   2.1e+02   5.7e+00   0.0e+00   9.1e-01
[ Info:      5   2.1e+02   2.0e+00   0.0e+00   4.1e-01
[ Info:      6   2.1e+02   1.4e+00   0.0e+00   3.9e-01
[ Info:      7   2.1e+02   1.4e+00   0.0e+00   4.4e-01
[ Info:      8   2.1e+02   1.5e+00   0.0e+00   4.4e-01
[ Info:      9   2.1e+02   1.1e+00   0.0e+00   3.2e-01
[ Info:     10   2.0e+02   8.1e-01   0.0e+00   2.9e-01
[ Info:     11   2.0e+02   5.6e-01   0.0e+00   1.8e-01
[ Info:     12   2.0e+02   3.1e-01   0.0e+00   1.4e-01
[ Info:     13   2.0e+02   1.8e-01   0.0e+00   8.4e-02
[ Info:     14   2.0e+02   1.2e-01   0.0e+00   7.0e-02
[ Info:     15   2.0e+02   1.0e-01   0.0e+00   6.8e-02
[ Info:     16   2.0e+02   8.7e-02   0.0e+00   6.6e-02
[ Info:     17   2.0e+02   7.2e-02   0.0e+00   6.4e-02
[ Info:     18   2.0e+02   5.5e-02   0.0e+00   3.9e-02
[ Info:     19   2.0e+02   3.9e-02   0.0e+00   3.5e-02
[ Info:     20   2.0e+02   3.2e-02   0.0e+00   3.0e-02
[ Info:     21   2.0e+02   2.6e-02   0.0e+00   3.6e-02
[ Info:     22   2.0e+02   2.5e-02   0.0e+00   4.0e-02
[ Info:     23   2.0e+02   2.3e-02   0.0e+00   4.0e-02
[ Info:     24   2.0e+02   2.1e-02   0.0e+00   3.8e-02
[ Info:     25   2.0e+02   2.1e-02   0.0e+00   3.5e-02
[ Info:     26   2.0e+02   2.1e-02   0.0e+00   3.1e-02
[ Info:     27   2.0e+02   2.0e-02   0.0e+00   3.5e-02
[ Info:     28   2.0e+02   1.6e-02   0.0e+00   3.9e-02
[ Info:     29   2.0e+02   9.2e-03   0.0e+00   3.8e-02
[ Info:     30   2.0e+02   8.4e-04   0.0e+00   3.0e-02
[ Info:     31   2.0e+02   1.0e-02   0.0e+00   2.6e-02
[ Info:     32   2.0e+02   2.0e-02   0.0e+00   2.4e-02
[ Info:     33   2.0e+02   1.0e-02   0.0e+00   2.6e-02
[ Info:     34   2.0e+02   5.0e-03   0.0e+00   3.0e-02
[ Info:     35   2.0e+02   4.5e-03   0.0e+00   3.3e-02
[ Info:     36   2.0e+02   4.5e-03   0.0e+00   3.5e-02
[ Info:     37   2.0e+02   4.8e-03   0.0e+00   3.7e-02
[ Info:     38   2.0e+02   5.4e-03   0.0e+00   3.8e-02
[ Info:     39   2.0e+02   5.9e-03   0.0e+00   3.7e-02
[ Info:     40   2.0e+02   6.4e-03   0.0e+00   3.6e-02
[ Info:     41   2.0e+02   7.0e-03   0.0e+00   3.4e-02
[ Info:     42   2.0e+02   7.9e-03   0.0e+00   3.5e-02
[ Info:     43   2.0e+02   9.1e-03   0.0e+00   3.7e-02
[ Info:     44   2.0e+02   1.1e-02   0.0e+00   3.8e-02
[ Info:     45   2.0e+02   1.1e-02   0.0e+00   5.0e-02
[ Info:     46   2.0e+02   1.2e-02   0.0e+00   6.2e-02
[ Info:     47   2.0e+02   1.4e-02   0.0e+00   7.4e-02
[ Info:     48   2.0e+02   2.0e-02   0.0e+00   8.5e-02
[ Info:     49   2.0e+02   2.5e-02   0.0e+00   8.8e-02
[ Info:     50   2.0e+02   3.3e-02   0.0e+00   9.4e-02
[ Info:     51   2.0e+02   4.1e-02   0.0e+00   1.0e-01
[ Info:     52   2.0e+02   4.9e-02   0.0e+00   1.1e-01
[ Info:     53   2.0e+02   5.5e-02   0.0e+00   1.0e-01
[ Info:     54   2.0e+02   4.7e-02   0.0e+00   9.8e-02
[ Info:     55   2.0e+02   3.8e-02   0.0e+00   8.4e-02
[ Info:     56   2.0e+02   3.3e-02   0.0e+00   7.1e-02
[ Info:     57   2.0e+02   2.9e-02   0.0e+00   6.5e-02
[ Info:     58   2.0e+02   2.9e-02   0.0e+00   5.7e-02
[ Info:     59   2.0e+02   2.4e-02   0.0e+00   4.8e-02
[ Info:     60   2.0e+02   1.9e-02   0.0e+00   3.9e-02
β=4.0: compliance = 202.5, gray = 0.298
[ Info:   iter       obj      Δobj  violation  kkt_residual  
[ Info:      0   1.7e+02       Inf   6.7e-02   6.7e-01
[ Info:      1   2.1e+02   3.8e+01   0.0e+00   4.4e+32
[ Info:      2   2.0e+02   6.6e+00   0.0e+00   1.6e+00
[ Info:      3   2.0e+02   2.6e+00   0.0e+00   5.7e-01
[ Info:      4   2.0e+02   1.4e+00   0.0e+00   4.0e-01
[ Info:      5   2.0e+02   1.1e+00   0.0e+00   4.3e-01
[ Info:      6   2.0e+02   1.1e+00   0.0e+00   4.5e-01
[ Info:      7   2.0e+02   9.5e-01   0.0e+00   2.9e-01
[ Info:      8   1.9e+02   7.8e-01   0.0e+00   2.4e-01
[ Info:      9   1.9e+02   6.4e-01   0.0e+00   2.0e-01
[ Info:     10   1.9e+02   4.4e-01   0.0e+00   1.7e-01
[ Info:     11   1.9e+02   2.4e-01   0.0e+00   8.1e-02
[ Info:     12   1.9e+02   1.3e-01   0.0e+00   7.2e-02
[ Info:     13   1.9e+02   1.0e-01   0.0e+00   5.2e-02
[ Info:     14   1.9e+02   7.0e-02   0.0e+00   5.0e-02
[ Info:     15   1.9e+02   5.7e-02   0.0e+00   4.8e-02
[ Info:     16   1.9e+02   4.7e-02   0.0e+00   3.5e-02
[ Info:     17   1.9e+02   3.0e-02   0.0e+00   3.9e-02
[ Info:     18   1.9e+02   2.1e-02   0.0e+00   4.1e-02
[ Info:     19   1.9e+02   1.6e-02   0.0e+00   4.0e-02
[ Info:     20   1.9e+02   1.2e-02   0.0e+00   3.9e-02
[ Info:     21   1.9e+02   1.1e-02   0.0e+00   3.9e-02
[ Info:     22   1.9e+02   1.1e-02   0.0e+00   4.0e-02
[ Info:     23   1.9e+02   1.3e-02   0.0e+00   4.3e-02
[ Info:     24   1.9e+02   1.5e-02   0.0e+00   5.0e-02
[ Info:     25   1.9e+02   1.7e-02   0.0e+00   3.7e-02
[ Info:     26   1.9e+02   1.7e-02   0.0e+00   3.9e-02
[ Info:     27   1.9e+02   1.9e-02   0.0e+00   3.9e-02
[ Info:     28   1.9e+02   2.1e-02   0.0e+00   3.8e-02
[ Info:     29   1.9e+02   2.4e-02   0.0e+00   4.1e-02
[ Info:     30   1.9e+02   2.3e-02   0.0e+00   3.7e-02
[ Info:     31   1.9e+02   1.3e-02   0.0e+00   3.9e-02
[ Info:     32   1.9e+02   6.7e-03   0.0e+00   3.3e-02
[ Info:     33   1.9e+02   4.8e-03   0.0e+00   3.5e-02
[ Info:     34   1.9e+02   4.2e-03   0.0e+00   3.6e-02
[ Info:     35   1.9e+02   5.9e-03   0.0e+00   3.3e-02
[ Info:     36   1.9e+02   5.4e-03   0.0e+00   3.5e-02
[ Info:     37   1.9e+02   4.7e-03   0.0e+00   3.1e-02
[ Info:     38   1.9e+02   2.2e-03   0.0e+00   3.2e-02
[ Info:     39   1.9e+02   2.4e-03   0.0e+00   3.2e-02
[ Info:     40   1.9e+02   2.6e-03   0.0e+00   3.1e-02
[ Info:     41   1.9e+02   2.8e-03   0.0e+00   3.1e-02
[ Info:     42   1.9e+02   3.1e-03   0.0e+00   2.9e-02
[ Info:     43   1.9e+02   3.4e-03   0.0e+00   2.7e-02
[ Info:     44   1.9e+02   3.8e-03   0.0e+00   2.5e-02
[ Info:     45   1.9e+02   4.2e-03   0.0e+00   2.3e-02
[ Info:     46   1.9e+02   4.7e-03   0.0e+00   2.1e-02
[ Info:     47   1.9e+02   5.1e-03   0.0e+00   1.9e-02
[ Info:     48   1.9e+02   5.0e-03   0.0e+00   1.4e-02
[ Info:     49   1.9e+02   4.6e-03   0.0e+00   1.3e-02
[ Info:     50   1.9e+02   4.4e-03   0.0e+00   1.9e-02
[ Info:     51   1.9e+02   4.2e-03   0.0e+00   2.3e-02
[ Info:     52   1.9e+02   3.4e-03   0.0e+00   2.6e-02
[ Info:     53   1.9e+02   3.0e-03   0.0e+00   3.0e-02
[ Info:     54   1.9e+02   1.9e-03   0.0e+00   3.0e-02
[ Info:     55   1.9e+02   1.4e-03   0.0e+00   2.9e-02
[ Info:     56   1.9e+02   1.2e-03   0.0e+00   2.7e-02
[ Info:     57   1.9e+02   1.3e-03   0.0e+00   2.5e-02
[ Info:     58   1.9e+02   1.3e-03   0.0e+00   2.3e-02
[ Info:     59   1.9e+02   1.4e-03   0.0e+00   2.0e-02
[ Info:     60   1.9e+02   1.4e-03   0.0e+00   1.7e-02
β=8.0: compliance = 192.79, gray = 0.248
[ Info:   iter       obj      Δobj  violation  kkt_residual  
[ Info:      0   1.7e+02       Inf   5.1e-02   1.2e+00
[ Info:      1   1.9e+02   2.2e+01   0.0e+00   2.5e+32
[ Info:      2   1.9e+02   1.0e+00   0.0e+00   4.2e-01
[ Info:      3   1.9e+02   5.2e-01   0.0e+00   3.2e-01
[ Info:      4   1.9e+02   4.1e-01   0.0e+00   2.6e-01
[ Info:      5   1.9e+02   4.1e-01   0.0e+00   2.3e-01
[ Info:      6   1.9e+02   4.3e-01   0.0e+00   1.9e-01
[ Info:      7   1.9e+02   3.4e-01   0.0e+00   2.0e-01
[ Info:      8   1.9e+02   2.9e-01   0.0e+00   2.1e-01
[ Info:      9   1.9e+02   2.7e-01   0.0e+00   1.3e-01
[ Info:     10   1.9e+02   2.2e-01   0.0e+00   1.3e-01
[ Info:     11   1.9e+02   1.9e-01   0.0e+00   1.4e-01
[ Info:     12   1.9e+02   1.3e-01   0.0e+00   1.1e-01
[ Info:     13   1.9e+02   8.9e-02   0.0e+00   8.2e-02
[ Info:     14   1.9e+02   6.4e-02   0.0e+00   6.3e-02
[ Info:     15   1.9e+02   5.2e-02   0.0e+00   7.2e-02
[ Info:     16   1.9e+02   4.8e-02   0.0e+00   8.0e-02
[ Info:     17   1.9e+02   3.8e-02   0.0e+00   6.6e-02
[ Info:     18   1.9e+02   3.2e-02   0.0e+00   5.2e-02
[ Info:     19   1.9e+02   3.2e-02   0.0e+00   4.4e-02
[ Info:     20   1.9e+02   2.4e-02   0.0e+00   4.3e-02
[ Info:     21   1.9e+02   2.1e-02   0.0e+00   4.5e-02
[ Info:     22   1.9e+02   1.6e-02   0.0e+00   3.4e-02
[ Info:     23   1.9e+02   1.3e-02   0.0e+00   1.5e-02
[ Info:     24   1.9e+02   8.0e-03   0.0e+00   1.4e-02
[ Info:     25   1.9e+02   7.7e-04   0.0e+00   2.6e-02
[ Info:     26   1.9e+02   1.6e-02   0.0e+00   3.9e-02
[ Info:     27   1.9e+02   4.2e-02   0.0e+00   6.1e-02
[ Info:     28   1.9e+02   2.5e-02   0.0e+00   9.4e-02
[ Info:     29   1.9e+02   2.9e-02   0.0e+00   7.2e-02
[ Info:     30   1.9e+02   5.4e-02   0.0e+00   3.0e-02
[ Info:     31   1.9e+02   2.4e-02   0.0e+00   2.7e-02
[ Info:     32   1.9e+02   6.3e-03   0.0e+00   2.7e-02
[ Info:     33   1.9e+02   1.9e-03   0.0e+00   2.6e-02
[ Info:     34   1.9e+02   1.3e-03   0.0e+00   2.5e-02
[ Info:     35   1.9e+02   1.3e-03   0.0e+00   2.3e-02
[ Info:     36   1.9e+02   8.6e-04   0.0e+00   2.1e-02
[ Info:     37   1.9e+02   3.7e-04   0.0e+00   2.2e-02
[ Info:     38   1.9e+02   9.0e-04   0.0e+00   2.2e-02
[ Info:     39   1.9e+02   2.2e-03   0.0e+00   2.2e-02
[ Info:     40   1.9e+02   4.2e-03   0.0e+00   2.1e-02
[ Info:     41   1.9e+02   2.0e-03   0.0e+00   2.0e-02
[ Info:     42   1.9e+02   1.4e-03   0.0e+00   1.7e-02
[ Info:     43   1.9e+02   1.3e-03   0.0e+00   1.4e-02
[ Info:     44   1.9e+02   1.2e-03   0.0e+00   1.1e-02
[ Info:     45   1.9e+02   1.1e-03   0.0e+00   1.1e-02
[ Info:     46   1.9e+02   4.3e-04   0.0e+00   9.6e-03
[ Info:     47   1.9e+02   5.4e-04   0.0e+00   1.6e-02
[ Info:     48   1.9e+02   4.7e-03   0.0e+00   2.8e-02
[ Info:     49   1.9e+02   4.6e-03   0.0e+00   3.1e-02
[ Info:     50   1.9e+02   3.1e-03   0.0e+00   3.0e-02
[ Info:     51   1.9e+02   7.4e-03   0.0e+00   2.2e-02
[ Info:     52   1.9e+02   3.6e-03   0.0e+00   1.1e-02
[ Info:     53   1.9e+02   1.5e-03   0.0e+00   6.3e-03
[ Info:     54   1.9e+02   7.7e-04   0.0e+00   6.4e-03
[ Info:     55   1.9e+02   4.2e-04   0.0e+00   6.8e-03
[ Info:     56   1.9e+02   2.6e-04   0.0e+00   6.9e-03
[ Info:     57   1.9e+02   3.4e-06   0.0e+00   7.1e-03
[ Info:     58   1.9e+02   2.8e-04   0.0e+00   9.2e-03
[ Info:     59   1.9e+02   5.6e-04   0.0e+00   6.4e-03
[ Info:     60   1.9e+02   1.0e-03   0.0e+00   7.0e-03
β=16.0: compliance = 188.13, gray = 0.209
1200-element Vector{Float64}:
 1.0
 1.0
 1.0
 1.0
 1.0
 1.0
 1.0
 1.0
 1.0
 1.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)
undeformed mesh
load arrows
support arrows
Figure 4: β-continuation (2 → 4 → 8 → 16): grayness decreases as the projection sharpens

The reported grayness drops as β increases, confirming that the projection continuation drives the design toward a crisp 0/1 distribution.