A lightweight, flexible Python library for topology optimization built on top of Scikit Libraries
To contribute to the open-source community and education—which I’ve always benefited from—I decided to start this project.
The currently supported features are as follows:
- Coding with Python
- easy installation with pip/poetry
- Implement FEA on unstructured mesh using scikit-fem
- Topology optimization using the density method and its optimization algorithm
- Optimality Criteria (OC) Method
- (Log-Space) Modified OC Method
- Lagrangian Method
- able to handle multiple objectives / constraints
- High-performance computation using sparse matrices with Scipy and PyAMG
- has a function to monitor the transition of parameters.
If you use Scikit Topt in your research or software, please cite it as:
@misc{scikit-topt2025,
author = {Watanabe, Kohei},
title = {Scikit-Topt: A Python Library for Algorithm Development in Topology Optimization},
year = {2025},
publisher = {Zenodo},
doi = {10.5281/zenodo.15441499},
url = {https://doi.org/10.5281/zenodo.15441499},
note = {Version 0.2.0}
}
pip install scikit-topt
poetry add scikit-topt
import skfem
import sktopt
mesh_path = "./data/model.msh"
basis = sktopt.mesh.loader.basis_from_file(
mesh_path, intorder=3
)
x_len, y_len, z_len = 1.0, 1.0, 1.0
element_size = 0.1
# import pathlib
# msh_path = "model.msh"
# mesh = skfem.MeshHex.load(pathlib.Path(msh_path))
# define basis
mesh = sktopt.mesh.toy_problem.create_box_hex(
x_len, y_len, z_len, element_size
)
e = skfem.ElementVector(skfem.ElementHex1())
basis = skfem.Basis(mesh, e, intorder=3)
# Specify Dirichlet Boundary Conditions
dirichlet_nodes = sktopt.mesh.utils.get_nodes_indices_in_range(
basis, (0.0, 0.03), (0.0, y_len), (0.0, z_len)
)
dirichlet_dir = "all"
# Define Force Vector
F_nodes = sktopt.mesh.utils.get_nodes_indices_in_range(
basis,
(x_len, x_len),
(y_len*2/5, y_len*3/5),
(z_len*2/5, z_len*3/5)
)
F_dir = "u^1"
F = 100
# Specify Design Field
design_elements = sktopt.mesh.utils.get_elements_in_box(
mesh,
(0.0, x_len), (0.0, y_len), (0.0, z_len)
)
# Define it as a task
tsk = sktopt.mesh.task.TaskConfig.from_nodes(
210e9,
0.30,
basis,
dirichlet_nodes,
dirichlet_dir,
F_nodes,
F_dir,
F,
design_elements
)
import sktopt
tsk = sktopt.mesh.toy_problem.toy1()
cfg = sktopt.core.LogMOC_Config()
optimizer = sktopt.core.LogMOC_Optimizer(cfg, tsk)
optimizer.parameterize()
optimizer.optimize()
OMP_NUM_THREADS=3 OPENBLAS_NUM_THREADS=3 MKL_NUM_THREADS=3 PYTHONPATH=./scikit-topt python ./sktopt/core/optimizer/logmoc.py \
--dst_path ./result/base_moc_down \
--interpolation SIMP \
--vol_frac 0.40 \
--eta 0.8 \
--record_times 100 \
--max_iters 600 \
--mu_p 2000 \
--task_name down_box \
--solver_option spsolve \
--rho_min 1e-2 \
--E0 210e9 \
--E_min 210e5 \
--design_dirichlet true
Optimization Algorithms and Techniques are briefly summarized here.
Optimization Algorithms and Techniques
This software does not exist in a vacuum. Scikit-Topt is standing on the shoulders of proverbial giants. In particular, I want to thank the following projects for constituting the technical backbone of the project:
- Scipy
- Scikit-fem
- PyAMG
- Numba
- MeshIO
- Matplotlib
- PyVista
- Topology Optimization Community
- Set break point from the optimization loop
- Add other optimizers
- Evolutionary Algorithms
- Level Set
- Phase Field
- MMA
- Add Multiple BC Conditions
- Add Constraint for Rotation