Continuous SIMP example

Tip

This example is also available as a Jupyter notebook: csimp.ipynb

Commented Program

What follows is a program spliced with comments. The full program, without comments, can be found in the next section.

using TopOpt

Define the problem

E = 1.0 # Young’s modulus
v = 0.3 # Poisson’s ratio
f = 1.0 # downward force

problems = Any[
    PointLoadCantilever(Val{:Linear}, (60, 20, 20), (1.0, 1.0, 1.0), E, v, f),
    PointLoadCantilever(Val{:Linear}, (160, 40), (1.0, 1.0), E, v, f),
    HalfMBB(Val{:Linear}, (60, 20), (1.0, 1.0), E, v, f),
    LBeam(Val{:Linear}, Float64; force=f),
    TieBeam(Val{:Quadratic}, Float64),
]
problem_names = [
    "3d cantilever beam", "cantilever beam", "half MBB beam", "L-beam", "tie-beam"
]

i = 2
println(problem_names[i])
problem = problems[i]

Parameter settings

V = 0.5 # volume fraction
xmin = 0.001 # minimum density
rmin = 3.0

convcriteria = Nonconvex.KKTCriteria()
x0 = fill(V, TopOpt.getncells(problem))
penalty = TopOpt.PowerPenalty(1.0)
solver = FEASolver(Direct, problem; xmin=xmin, penalty=penalty)
comp = Compliance(solver)
filter = if problem isa TopOptProblems.TieBeam
    identity
else
    DensityFilter(solver; rmin=rmin)
end
obj = x -> comp(filter(PseudoDensities(x)))
#1 (generic function with 1 method)

Define volume constraint

volfrac = Volume(solver)
constr = x -> volfrac(filter(PseudoDensities(x))) - V
model = Model(obj)
addvar!(model, zeros(length(x0)), ones(length(x0)))
add_ineq_constraint!(model, constr)
alg = MMA87()

nsteps = 4
ps = range(1.0, 5.0; length=nsteps + 1)
1.0:1.0:5.0

exponentially decaying tolerance from 10^-2 to 10^-4

tols = exp10.(range(-2, -4; length=nsteps + 1))
x = x0
for j in 1:(nsteps + 1)
    global convcriteria
    p = ps[j]
    tol = tols[j]
    TopOpt.setpenalty!(solver, p)
    options = MMAOptions(; tol=Tolerance(; kkt=tol), maxiter=1000, convcriteria)
    res = optimize(model, alg, x; options)
    global x = res.minimizer
end

@show obj(x)
@show constr(x)
-7.087833098218255e-10

(Optional) Visualize the result using Makie.jl

Need to run using Pkg; Pkg.add("Makie") first and either Pkg.add("CairoMakie") or Pkg.add("GLMakie")

using Makie
using CairoMakie

alternatively, using GLMakie

fig = visualize(
    problem;
    topology=x,
    default_exagg_scale=0.07,
    scale_range=10.0,
    vector_linewidth=3,
    vector_arrowsize=0.5,
)
Makie.display(fig)
CairoMakie.Screen{IMAGE}

Plain Program

Below follows a version of the program without any comments. The file is also available here: csimp.jl

using TopOpt

E = 1.0 # Young’s modulus
v = 0.3 # Poisson’s ratio
f = 1.0 # downward force

problems = Any[
    PointLoadCantilever(Val{:Linear}, (60, 20, 20), (1.0, 1.0, 1.0), E, v, f),
    PointLoadCantilever(Val{:Linear}, (160, 40), (1.0, 1.0), E, v, f),
    HalfMBB(Val{:Linear}, (60, 20), (1.0, 1.0), E, v, f),
    LBeam(Val{:Linear}, Float64; force=f),
    TieBeam(Val{:Quadratic}, Float64),
]
problem_names = [
    "3d cantilever beam", "cantilever beam", "half MBB beam", "L-beam", "tie-beam"
]

i = 2
println(problem_names[i])
problem = problems[i]

V = 0.5 # volume fraction
xmin = 0.001 # minimum density
rmin = 3.0

convcriteria = Nonconvex.KKTCriteria()
x0 = fill(V, TopOpt.getncells(problem))
penalty = TopOpt.PowerPenalty(1.0)
solver = FEASolver(Direct, problem; xmin=xmin, penalty=penalty)
comp = Compliance(solver)
filter = if problem isa TopOptProblems.TieBeam
    identity
else
    DensityFilter(solver; rmin=rmin)
end
obj = x -> comp(filter(PseudoDensities(x)))

volfrac = Volume(solver)
constr = x -> volfrac(filter(PseudoDensities(x))) - V
model = Model(obj)
addvar!(model, zeros(length(x0)), ones(length(x0)))
add_ineq_constraint!(model, constr)
alg = MMA87()

nsteps = 4
ps = range(1.0, 5.0; length=nsteps + 1)

tols = exp10.(range(-2, -4; length=nsteps + 1))
x = x0
for j in 1:(nsteps + 1)
    global convcriteria
    p = ps[j]
    tol = tols[j]
    TopOpt.setpenalty!(solver, p)
    options = MMAOptions(; tol=Tolerance(; kkt=tol), maxiter=1000, convcriteria)
    res = optimize(model, alg, x; options)
    global x = res.minimizer
end

@show obj(x)
@show constr(x)

using Makie
using CairoMakie

fig = visualize(
    problem;
    topology=x,
    default_exagg_scale=0.07,
    scale_range=10.0,
    vector_linewidth=3,
    vector_arrowsize=0.5,
)
Makie.display(fig)

# This file was generated using Literate.jl, https://github.com/fredrikekre/Literate.jl

This page was generated using Literate.jl.