Skip to content

jezekon/EasySIMP.jl

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

180 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

EasySIMP.jl

EasySIMP is a Julia package for topology optimization using the Solid Isotropic Material with Penalization (SIMP) method, based on Sigmund (2001). It provides an intuitive interface suitable for educational purposes and practical applications. For usage examples, see test/Examples/.

Gripper topology optimization result

Features

  • SIMP Optimization: Classic topology optimization with penalization parameter control and sensitivity filtering
  • Mesh Support: Linear hexahedral and tetrahedral elements; supports VTU import and simple hexahedral mesh generation
  • Boundary Conditions: Fixed supports, sliding planes, distributed forces, surface traction, and body forces
  • Progress Monitoring: Real-time optimization progress with energy and volume tracking
  • ParaView Export: VTU output with density field, displacement, and stress

Installation

Requirements: Julia ≥ 1.10

# From Julia REPL, press ] to enter package mode
pkg> add https://github.com/jezekon/EasySIMP.jl

or

git clone https://github.com/jezekon/EasySIMP.jl

API Overview

The package exports the following symbols, grouped by module:

Group Exported symbols
Mesh import import_mesh
FEM setup & material setup_problem, create_material_model, create_simp_material_model, assemble_stiffness_matrix_simp!
Boundary conditions apply_fixed_boundary!, apply_sliding_boundary!
Forces apply_force!, apply_surface_traction!, get_boundary_facets
Node selection select_nodes_by_plane, select_nodes_by_circle, select_nodes_by_cylinder, select_nodes_by_arc
Optimization simp_optimize, OptimizationParameters
Load conditions AbstractLoadCondition, PointLoad, SurfaceTractionLoad
Filter cache (advanced) FilterCache, create_filter_cache
Post-processing export_results_vtu, create_results_data, export_boundary_conditions
Utilities calculate_volume, print_info, print_success, print_warning, print_error, print_data

Main Function

Run SIMP topology optimization:

simp_optimize(grid, dh, cellvalues, forces, boundary_conditions, params, acceleration_data)

Parameters

  • grid::Grid: Ferrite Grid object containing the mesh
  • dh::DofHandler: Degree of freedom handler from Ferrite
  • cellvalues: CellValues for finite element integration
  • forces: Vector of load conditions - either AbstractLoadCondition types (PointLoad, SurfaceTractionLoad) or legacy tuples (dh, node_indices, force_vector)
  • boundary_conditions: Vector of constraint handlers (fixed or sliding)
  • params::OptimizationParameters: Configuration options
  • acceleration_data: Optional tuple (acceleration_vector, base_density) for body forces

Return Value

  • OptimizationResult: Complete optimization results including densities, displacements, stresses, and convergence history
  • Output files: .vtu mesh files for visualization in ParaView

OptimizationParameters

Configure the optimization process with the following options:

params = OptimizationParameters(;
    E0 = 1.0,                              # Young's modulus of solid material
    Emin = 1e-9,                           # Young's modulus of void (numerical stability)
    ν = 0.3,                               # Poisson's ratio
    p = 3.0,                               # SIMP penalization parameter
    volume_fraction = 0.5,                 # Target volume fraction (0-1)
    max_iterations = 200,                  # Maximum optimization iterations
    tolerance = 0.01,                      # Convergence tolerance
    filter_radius = 1.5,                   # Filter radius (× element size)
    filter_type = :sensitivity,            # Filter type: :sensitivity or :density
    move_limit = 0.2,                      # Maximum density change per iteration
    damping = 0.5,                         # Optimality criteria damping factor
    use_cache = true,                      # Enable performance caching
    export_interval = 0,                   # Export every N iterations (0 = disabled)
    export_path = "",                      # Path for intermediate results
    task_name = "SIMP_Optimization",       # Name for logging files
    tolerance_checkpoints = Float64[]      # Extra tolerances to export at (multi-tol study)
)

Option Details

  • E0: Young's modulus of the solid material (typically 1.0 for normalized, or actual values like 200 GPa for steel)
  • Emin: Minimum stiffness to avoid singularity (recommended: 1e-6 to 1e-9)
  • ν: Poisson's ratio of the material
  • p: SIMP penalization parameter (typically 3.0)
  • volume_fraction: Target volume constraint as fraction of total volume
  • filter_radius: Controls smoothing of the filter field (1.5-2.5 × average element size recommended)
  • filter_type: :sensitivity (default — filters the sensitivity field) or :density (filters the density field)
  • export_interval: When > 0, exports intermediate results every N iterations for animation
  • use_cache: Enables caching of element stiffness matrices for improved performance
  • task_name: Identifier for logging and summary files
  • tolerance_checkpoints: Optional list of intermediate tolerance values; when supplied, results are also exported each time convergence drops below one of these values (useful for tolerance sensitivity studies — see test/Examples/05_3D_2x1x1_4Legs_tol_study.jl)

Example Usage

using EasySIMP
using Ferrite

# 1. Generate or import mesh
grid = generate_grid(Hexahedron, (60, 20, 4),  # nelements: (nx, ny, nz)
                     Vec((0.0, 0.0, 0.0)),     # lower corner
                     Vec((60.0, 20.0, 4.0)))   # upper corner

# 2. Setup FEM problem
dh, cellvalues, K, f = setup_problem(grid)

# 3. Define boundary conditions
fixed_nodes = select_nodes_by_plane(grid, [0.0, 0.0, 0.0], [1.0, 0.0, 0.0], 1e-3) # point, normal, tol
force_nodes = select_nodes_by_circle(grid, [60.0, 0.0, 2.0], [1.0, 0.0, 0.0], 1.0) # center, normal, radius

# 4. Apply boundary conditions
material_model = create_simp_material_model(200.0, 0.3, 1e-6, 3.0) # E0, ν, Emin, p
assemble_stiffness_matrix_simp!(K, f, dh, cellvalues, material_model, 
                                fill(0.4, getncells(grid)))
ch_fixed = apply_fixed_boundary!(K, f, dh, fixed_nodes)

# 5. Configure optimization
opt_params = OptimizationParameters(
    E0 = 200.0,
    volume_fraction = 0.4,
    max_iterations = 100,
    filter_radius = 2.5,
    export_interval = 5,
    export_path = "./results"
)

# 6. Run optimization
results = simp_optimize(
    grid, dh, cellvalues,
    [PointLoad(dh, collect(force_nodes), [0.0, -1.0, 0.0])], # forces
    [ch_fixed],                                     # boundary conditions
    opt_params
)

# 7. Export results
results_data = create_results_data(grid, dh, cellvalues, results)
export_results_vtu(results_data, "cantilever_beam")

Advanced Usage Examples

For complete examples with detailed documentation, see test/Examples/:

# Simple cantilever beam with fixed support
julia --project=. test/Examples/01_basic_cantilever.jl

# Beam with sliding (symmetry) boundary condition
julia --project=. test/Examples/02_sliding_support.jl

# Beam under acceleration (body forces)
julia --project=. test/Examples/03_with_acceleration.jl

# Multi-objective gripper with imported mesh
julia --project=. test/Examples/04_gripper_complex.jl

Additional examples (MBB beam, wheel with surface traction, etc.) are available in the test/Examples/ directory.

Visualization in ParaView

  1. Load the output VTU file in ParaView
  2. Apply Threshold filter on density field
  3. Set lower threshold (e.g., 0.3-0.5) to show solid regions

For intermediate results animation:

  1. Load all iter_*.vtu files as a time series
  2. Animate to see optimization convergence

Acknowledgments

This package implements the classic SIMP method for topology optimization. The implementation is inspired by the educational paper "A 99 line topology optimization code written in Matlab" by Sigmund (2001). Built on Ferrite.jl for finite element analysis.

Packages

 
 
 

Contributors