GESO: Genetic Evolutionary Structural Optimization

Description

GESO (Genetic Evolutionary Structural Optimization) is a hybrid algorithm that combines evolutionary structural optimization with genetic algorithm concepts. Unlike BESO which uses sensitivity-based element removal/addition, GESO employs binary encoding of design variables and genetic operators (crossover, mutation) to explore the design space.

This tutorial solves the same HalfMBB beam problem as the BESO tutorial, but using the GESO algorithm. GESO is particularly useful when dealing with discrete design variables and can escape local minima through its stochastic search strategy.

Setup

Load the TopOpt package:

using TopOpt
Precompiling packages...
   2035.5 msQuartoNotebookWorkerTablesExt (serial)
  1 dependency successfully precompiled in 2 seconds
Precompiling packages...
   1040.1 msQuartoNotebookWorkerJSONExt (serial)
  1 dependency successfully precompiled in 1 seconds
Precompiling packages...
    974.8 msQuartoNotebookWorkerJSON3Ext (serial)
  1 dependency successfully precompiled in 1 seconds
Precompiling packages...
    961.1 msQuartoNotebookWorkerLaTeXStringsExt (serial)
  1 dependency successfully precompiled in 1 seconds

Define the problem

We use the same 2D HalfMBB benchmark with 160×40 elements:

E = 1.0 # Young's modulus (normalized)
v = 0.3 # Poisson's ratio
f = 1.0 # downward force magnitude

nels = (160, 40)  # 160 elements in x, 40 in y
problem = HalfMBB(Val{:Linear}, nels, (1.0, 1.0), E, v, f)
TopOpt half MBB problem

Define the FEA solver and apply material penalization

The FEA solver uses power-law penalization to drive toward 0/1 designs:

solver = FEASolver(DirectSolver, problem; xmin=0.01, penalty=PowerPenaltyFun(3.0))
TopOpt direct structural solver (GenericFEASolver)

Define the compliance objective and volume constraint

GESO requires:

  1. Objective: Compliance to minimize
  2. Constraint: Volume fraction limit
  3. Filter: Sensitivity filter for mesh independence
comp = ComplianceFun(solver)
volfrac = VolumeFun(solver)
sensfilter = SensFilterFun(solver; rmin=4.0)
geso = GESO(comp, volfrac, 0.5, sensfilter)  # target volume = 50%
TopOpt GESO algorithm

The GESO algorithm uses:

  • Binary encoding of design variables (string length = 4 bits per element)
  • Crossover probability (Pcmin=0.6, Pcmax=1.0)
  • Mutation probability (Pmmin=0.5, Pmmax=1.0)
  • Penalty parameter (Pen=3.0) for constraint handling

Run the GESO optimization

The GESO algorithm iterates:

  1. Encode current design as binary strings
  2. Evaluate fitness (compliance + penalty for constraint violation)
  3. Apply genetic operators: selection, crossover, mutation
  4. Decode binary strings to get new design
  5. Filter sensitivities for stability
  6. Check convergence
x0 = ones(length(solver.vars))  # start from fully solid design
result = geso(x0)
TopOpt.Algorithms.GESOResult{Float64, 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, 0.0], 347.7954102356539, 3.175360018052111e-5, true, 1000)

GESO typically requires more iterations than BESO (100-200+) due to its stochastic nature, but can find better global optima for complex problems.

Visualize the result

using CairoMakie
fig = visualize(problem; topology=result.topology)
Precompiling packages...
   5703.3 msQuartoNotebookWorkerMakieExt (serial)
  1 dependency successfully precompiled in 6 seconds
Precompiling packages...
   4722.5 msQuartoNotebookWorkerCairoMakieExt (serial)
  1 dependency successfully precompiled in 5 seconds
Figure 1: GESO optimization result showing the evolved beam structure

The result shows a truss-like structure optimized for minimum compliance under the 50% volume constraint.