Harmonic Response, Thermal-Expansion, and Two-Scale Topology Optimization
Overview
Three frequency/scale-aware goals:
- Harmonic (frequency-response) optimization — minimize the dynamic compliance of the forced undamped system
(K − ω²M)u = fat a driving frequencyω, so the structure is stiff under sinusoidal loading. - Thermal-expansion metamaterials — design a periodic cell with a prescribed effective thermal-expansion coefficient (e.g. near-zero, to avoid thermal warping).
- Two-scale design — optimize the microstructure of a periodic cell so a macro structure built from it is as stiff as possible.
Harmonic response
harmonic_topopt minimizes J = fᵀu of (K − ω²M)u = f:
using Rasmah
m = tetrahedralize_box(1.0, 1.0, 1.0, 3, 3, 3)
bs = box_boundary_sets(m, 1.0, 1.0, 1.0)
fixed = dofs(m, bs[:zmin])
xh, histh = harmonic_topopt(m, 1e3, 0.3, 1.0, fixed,
face_load(m, bs[:zmax], [1.0, 0.0, 0.0]), 10.0, 0.5,
fill(0.5, size(m.elements, 2)); maxiter = 30)
println("dynamic compliance ", round(histh[1]; digits = 3), " → ", round(histh[end]; digits = 3))
vtk(m; field = xh, fieldname = "density", edges = true)dynamic compliance 0.128 → 0.009
Thermal-expansion metamaterial
thermal_expansion_homogenize computes the effective expansion of a cell; thermal_expansion_topopt drives it to a target (here zero):
E, ν, α = 1e3, 0.3, 1e-5
C = Matrix(elasticity_matrix(E, ν))
# a homogeneous cell expands by its own α
println("homogeneous α_H = ", round(thermal_expansion_homogenize(m, fill(1.0, size(m.elements, 2)), C, α); sigdigits = 3))
res = thermal_expansion_topopt(m, C, α, 0.0, fill(0.5, size(m.elements, 2)); volfrac = 0.5, maxiter = 40)
println("optimized α_H = ", round(res.α_H; sigdigits = 3), " (target 0)")
vtk(m; field = res.ρ, fieldname = "cell density", edges = true)homogeneous α_H = 1.0e-5
optimized α_H = 1.0e-5 (target 0)
Two-scale design
two_scale_topopt optimizes a unit cell so the macro compliance (of a 2D plane stress part made from the homogenized material) is minimized:
g = LevelSetGrid(6, 6, 1.0 / 5, 1.0 / 5)
gm = grid_triangle_mesh(g)
N = size(gm.vertices, 2)
fixed2 = Int[]; loads2 = zeros(2N)
for i in 1:N
x = gm.vertices[:, i]
x[1] < 1e-12 && append!(fixed2, 2i - 1, 2i)
x[1] > 1 - 1e-12 && (loads2[2i] = -1.0)
end
cell = tetrahedralize_box(1.0, 1.0, 1.0, 2, 2, 2)
rest = two_scale_topopt(gm, 1e3, 0.3, fixed2, loads2, cell, C, 0.5,
fill(0.5, size(cell.elements, 2)); maxiter = 20)
println("macro compliance trace ", round(rest.history[1]; digits = 3), " → ", round(rest.history[end]; digits = 3))
vtk(cell; field = rest.x, fieldname = "micro density", edges = true)macro compliance trace 1.69 → 1.69
Next steps
- Eigenfrequency and buckling — the eigen-problem cousins of the harmonic response.
- Homogenization and metamaterials — the effective-material machinery behind thermal-expansion and two-scale.
- Geometrically nonlinear — large-deformation design.
