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_minimization — Function
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_minimization — Function
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_3d — Function
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.LevelSetResult — Type
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.LevelSetBoundaryConditions — Type
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_fractions — Function
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.LevelSetMesh — Type
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.LevelSet — Type
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.LevelSetHole — Type
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.FastMarchingMethod — Type
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.Heap — Type
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.LevelSetOptimizer — Type
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.FEMesh — Type
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.SolidMaterial — Type
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.SolidElement — Type
SolidElement

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

source
TopOpt.OpenLSTO.StationaryStudy — Type
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.HexMaterial — Type
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.HexStudy — Type
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.LevelSet3D — Type
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_sensitivity — Function
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_vtk — Function
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_txt — Function
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_txt — Function
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_vtk — Function
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