OpenLSTO

This sub-module of TopOpt is a self-contained Julia translation of the level-set topology optimization method in OpenLSTO. It implements the 2D compliance-minimization workflow (with optional hole nucleation) and the 2D L-beam stress-minimization workflow, on its own mesh, fast marching, boundary discretization, and finite element solver.

Optimization drivers

TopOpt.OpenLSTO.compliance_minimizationFunction
compliance_minimization(; nelx, nely, ...)

Run the OpenLSTO level-set compliance-minimization loop on the cantilever problem (left edge fixed, downward point load at the midpoint of the right edge). Returns a LevelSetResult with the final level_set, boundary, study, sensitivities, and the per-iteration objectives and areas.

Keyword arguments:

  • nelx, nely: number of finite elements (and level-set cells) in x and y.
  • E, nu, rho: material properties (Young's modulus, Poisson's ratio, density).
  • holes: initial circular holes; defaults to the Swiss-cheese arrangement.
  • move_limit, band_width, is_fixed_domain: level-set parameters.
  • max_iterations, max_area, max_diff: stopping criteria.
  • hole_nucleation: enable the hole-nucleation scheme (a port of projects/hole_creation); hole_cfl, hole_l_band, and new_hole_area_limit tune it.

Example (the OpenLSTO cantilever demo)

holes = [LevelSetHole(16, 14, 5), LevelSetHole(48, 14, 5), LevelSetHole(80, 14, 5), LevelSetHole(112, 14, 5), LevelSetHole(144, 14, 5), LevelSetHole(32, 27, 5), LevelSetHole(64, 27, 5), LevelSetHole(96, 27, 5), LevelSetHole(128, 27, 5), LevelSetHole(16, 40, 5), LevelSetHole(48, 40, 5), LevelSetHole(80, 40, 5), LevelSetHole(112, 40, 5), LevelSetHole(144, 40, 5), LevelSetHole(32, 53, 5), LevelSetHole(64, 53, 5), LevelSetHole(96, 53, 5), LevelSetHole(128, 53, 5), LevelSetHole(16, 66, 5), LevelSetHole(48, 66, 5), LevelSetHole(80, 66, 5), LevelSetHole(112, 66, 5), LevelSetHole(144, 66, 5)] result = compliance_minimization(; nelx=160, nely=80, holes)

source
TopOpt.OpenLSTO.stress_minimizationFunction
stress_minimization(; nelx, nely, ...)

Run the OpenLSTO level-set stress-minimization loop on the L-beam problem (top edge fixed, downward point load on the right edge at 2/5 height). The objective is the p-norm of the von Mises stress; the sensitivities use the adjoint method (compute_stress_sensitivities!). Returns a LevelSetResult whose objectives field holds the per-iteration p-norm stress.

Keyword arguments:

  • nelx, nely: number of finite elements (and level-set cells) in x and y.
  • E, nu, rho: material properties.
  • holes: initial circular holes; defaults to the five-hole L-beam seeding.
  • move_limit, band_width: level-set parameters.
  • max_iterations, max_area, max_diff, p_norm, reduced_move_limit: stopping and optimization parameters.
source
TopOpt.OpenLSTO.compliance_minimization_3dFunction
compliance_minimization_3d(; nelx, nely, nelz, ...)

Run the OpenLSTO 3D level-set compliance-minimization loop on a cantilever (left face fixed, downward line load on the bottom edge of the right face). Returns a NamedTuple with the final level_set (LevelSet3D), the HexStudy, the boundary conditions, and the per-iteration compliances and volume-fraction areas.

Like the upstream projects/3d/comp_min.cpp, only the load region is pinned solid by default (pin_support=:none). To also keep material on the left-face supports — which the optimizer can otherwise erode onto void — pass pin_support=:soft (a large support sensitivity, analogous to the load pin) or pin_support=:hard (clamp the signed distance on the support face so the contour cannot recede past it).

source
TopOpt.OpenLSTO.LevelSetResultType
LevelSetResult

The result of compliance_minimization or stress_minimization. Holds the final level set, its discretized boundary, the finite element study and sensitivities, the per-iteration objective and area-fraction histories, and the problem's boundary conditions.

Fields:

  • level_set: the final LevelSet (signed distance on the grid).
  • boundary: the final LevelSetBoundary discretization.
  • study: the StationaryStudy holding the last FEA solve.
  • sensitivities: the SensitivityAnalysis from the last iteration.
  • boundary_conditions: the LevelSetBoundaryConditions (loads and supports) of the problem.
  • objectives: per-iteration objective (compliance or p-norm stress) values.
  • areas: per-iteration volume-fraction values.
source
TopOpt.OpenLSTO.LevelSetBoundaryConditionsType
LevelSetBoundaryConditions

The load and support (Dirichlet) specification of a level-set problem, carried by LevelSetResult so visualize can draw the load and support arrows without reconstructing them from the finite element vectors.

Fields:

  • loads: (node, load vector) pairs, one per applied load.
  • supports: (component, node indices) pairs, one per constrained direction.
source
TopOpt.OpenLSTO.area_fractionsFunction
area_fractions(result::LevelSetResult)

Re-discretize the final level set and return the per-cell material area fraction, i.e. the density field of the optimized design. The vector has one entry per cell, ordered row-major (x fastest) to match the finite element mesh of result.study.

source

Level-set representation

TopOpt.OpenLSTO.LevelSetMeshType
LevelSetMesh(width, height)

The level-set fixed grid: a width × height array of unit-square cells with one node per grid point, used to represent the signed-distance function. Node coordinates are (x, y) with x ∈ 0:width, y ∈ 0:height. LevelSetMesh is the level-set counterpart of the Ferrite grids used by the rest of TopOpt.jl.

source
TopOpt.OpenLSTO.LevelSetType
LevelSet(mesh; move_limit=0.5, band_width=6, is_fixed=false)
LevelSet(mesh, holes; move_limit=0.5, band_width=6, is_fixed=false)

A signed-distance level set on a LevelSetMesh. Positive values are inside the structure, negative outside. The zero contour is advanced by a normal velocity extended from the boundary points, reinitialized by the fast marching method. holes seeds the initial configuration (default: the "Swiss cheese" arrangement of circular holes).

source
TopOpt.OpenLSTO.LevelSetHoleType
LevelSetHole(x, y, r)

A circular hole used to seed the initial level-set configuration: the region inside the circle (distance to the centre less than r) is material-free.

source

Fast marching and optimization

TopOpt.OpenLSTO.FastMarchingMethodType
FastMarchingMethod(mesh)

Solves the Eikonal equation by the fast marching method to reinitialise a signed-distance function or to extend boundary velocities through the narrow band. A port of M2DO_LSM/src/fast_marching_method.cpp, adapted from Scikit-FMM. Use march! to run it.

source
TopOpt.OpenLSTO.HeapType
Heap(max_length)

A binary min-heap used as the priority queue of the FastMarchingMethod. It stores (address, distance) pairs and is a faithful port of OpenLSTO's M2DO_LSM/src/heap.cpp, itself adapted from Scikit-FMM.

source
TopOpt.OpenLSTO.LevelSetOptimizerType
LevelSetOptimizer(boundary_points, move_limit)

Solves for the boundary-point velocities that advance the level set while satisfying the volume constraint. Uses a Newton-Raphson iteration on the Lagrange multiplier (a port of M2DO_LSM/src/optimise.cpp).

source

Finite element analysis

TopOpt.OpenLSTO.FEMeshType
FEMesh(nelx, nely)

The structured nelx × nely finite element mesh (unit-square Q4 cells) used for the level-set compliance solve. Independent of the level-set LevelSetMesh but with matching cell ordering.

source
TopOpt.OpenLSTO.SolidMaterialType
SolidMaterial(E, ν, ρ; h=1.0)

Plane-stress material with Young's modulus E, Poisson's ratio ν, density ρ, and thickness h. Stores the 4×4 constitutive matrix C and the 4×4 Voigt matrix V used for von Mises stress (σᵀ V σ = σ_vm² in the strain ordering of C).

source
TopOpt.OpenLSTO.SolidElementType
SolidElement

A single 4-node (Q4) plane-stress finite element: its node indices, global dofs, material area fraction, and centroid.

source
TopOpt.OpenLSTO.StationaryStudyType
StationaryStudy(mesh, material, fixed_dofs)

A linear static study K u = f for the level-set FEA: assembles the area-fraction-weighted stiffness matrix and solves it with a conjugate gradient method. Holds K, f, and the solution u.

source
TopOpt.OpenLSTO.HexMaterialType
HexMaterial(E, ν, ρ)

Isotropic 3D material with Young's modulus E, Poisson's ratio ν, and density ρ. Stores the 6x6 Voigt constitutive matrix C.

source
TopOpt.OpenLSTO.HexStudyType
HexStudy(nelx, nely, nz, material, fixed_dofs)

A structured nelx x nely x nelz hex mesh with a K u = f stationary study, assembled with element area fractions and solved by conjugate gradient.

source

3D level-set method

TopOpt.OpenLSTO.LevelSet3DType
LevelSet3D(nx, ny, nz)

A signed-distance level set on a 3D structured grid of nx x ny x nz cells. Positive values are inside the structure. The zero surface is discretized with marching cubes and advected by boundary velocities.

source

Internal helpers

TopOpt.OpenLSTO.discretise!Function
discretise!(boundary, size_lambdas)

Discretize the zero contour of the level set into boundary points and segments with marching squares.

source
TopOpt.OpenLSTO.march!Function
march!(fmm, signedDistance)
march!(fmm, signedDistance, velocity)

Run the fast marching method to reinitialize signedDistance to a signed distance function, or (with velocity) to extend boundary velocities through the narrow band without changing the signed distance.

source
TopOpt.OpenLSTO.compute_stress_sensitivities!Function
compute_stress_sensitivities!(sens, p_norm)

Compute the p-norm von Mises stress objective (Σ (ρ_e σ_vm)^p)^(1/p) and its adjoint-based sensitivity at each Gauss point. Sets sens.objective and sens.von_mises_max.

source
TopOpt.OpenLSTO.compute_boundary_sensitivityFunction
compute_boundary_sensitivity(sens, boundary_point; radius, indicator, p_norm)

Interpolate Gauss-point sensitivities to a boundary point by weighted least squares. indicator == 0 returns the compliance sensitivity; indicator == 1 combines the two stress sensitivity components into the p-norm stress sensitivity.

source

Input and output

TopOpt.OpenLSTO.save_level_set_vtkFunction
save_level_set_vtk(level_set, datapoint; is_velocity=false, is_gradient=false, output_directory="")
save_level_set_vtk(level_set, filename; is_velocity=false, is_gradient=false)

Write the signed distance function of a LevelSet as a ParaView VTK rectilinear grid, optionally including the nodal velocity and gradient fields.

source
TopOpt.OpenLSTO.save_level_set_txtFunction
save_level_set_txt(level_set, datapoint; output_directory="", is_xy=false)
save_level_set_txt(level_set, filename; is_xy=false)

Write the signed distance, velocity, and gradient of a LevelSet as plain text, optionally prefixed by the nodal x/y coordinates.

source
TopOpt.OpenLSTO.save_area_fractions_txtFunction
save_area_fractions_txt(mesh, datapoint; output_directory="", is_xy=false)
save_area_fractions_txt(mesh, filename; is_xy=false)

Write the element area fractions of a LevelSetMesh as plain text, optionally prefixed by the element centre coordinates.

source
TopOpt.OpenLSTO.boundary_vtkFunction
boundary_vtk(filename, boundary_points, sensitivities, neighbors)

Write boundary points and their sensitivity fields as a ParaView VTK unstructured grid of line segments. boundary_points is a vector of coordinates, sensitivities a vector of per-field point values, and neighbors the (start, end) index pairs of the segments.

source