Tutorial on Topology Optimization
Compliance minimization with local density constraint (created by Ruijin Cang)
Introduction
With great power comes great responsibility. The recent advances in 3D printing (overview slides) allowed unprecedented opportunities in creating complex geometries for all kinds of applications from soft robots to customized prosthetics to light-weight energy absorbers. The question is: How do we systematically create these complex geometries? Topology optimization is the answer.
The goal of this tutorial is to help you to learn topology optimization without any background knowledge, although you do need to be prepared for calculus and linear algebra. Please also read my previous post on finite element analysis if you are not familiar with the topic.
The tutorial is modified from my post for the optimization class, with additional explanations added when necessary. It is also based on Dr. Sigmund’s topology optimization code and paper.
Explanation of the mathematical problem behind compliance minimization
Recall that one typical form of topology optimization uses the compliance of the structure as the design objective. Two reasons for this: One, it is common that one wants a structure to be compliant or stiff (or a mixture of both); second, compliance is not only easy to compute but also (relatively) easy to differentiate, which, as we will see, is the key to topology optimization.
Notations
Following the previous discussion, the structure under design is segmented into \(n\) finite elements, and a density value \(x_i\) is assigned to each element \(i \in \{1,2,...,n\}\): A higher density corresponds to a less porous material element and higher Yong’s modulus. Reducing the density to zero is equivalent to creating a hole in the structure. Thus, the set of densities \({\bf x}=\{x_i\}\) can be used to represent the topology of the structure and is considered as the variables to be optimized. See figure here.
Problem statement
The compliance minimization problem is formulated as follows:
\[\min_{\bf x} \quad {\bf f} := {\bf d}^T {\bf K}({\bf x}) {\bf d}\] \[\text{subject to:} \quad {\bf h} := {\bf K}({\bf x}) {\bf d} = {\bf u},\] \[\quad {\bf g} := V(\textbf{x}) \leq v,\] \[\textbf{x} \in [0,1].\]Here \(V(\textbf{x})\) is the total volume; \(v\) is an upper bound on volume; \({\bf d} \in \mathbb{R}^{n_d\times 1}\) is the displacement of the structure under the load \({\bf u}\), where \(n_d\) is the degrees of freedom (DOF) of the system (i.e., the number of x- and y-coordinates of nodes from the finite element model of the structure); \({\bf K(x)}\) is the global stiffness matrix for the structure.
\({\bf K(x)}\) is indirectly influenced by the topology \({\bf x}\), through the element-wise stiffness matrix
\[{\bf K}_i = \bar{\bf K}_e E(x_i),\]and the local-to-global assembly:
\[{\bf K(x)} = {\bf G}[{\bf K}_1,{\bf K}_2,...,{\bf K}_n],\]where the matrix \(\bar{\bf K}_e\) is predefined according to the finite element type (we use first-order quadrilateral elements throughout this tutorial) and the nodal displacements of the element (we use square elements with unit lengths throughout this tutorial), \({\bf G}\) is an assembly matrix, \(E(x_i)\) is the element-wise Young’s modulus defined as a function of the density \(x_i\): \(E(x_i) := \Delta E x_i^p + E_{\text{min}}\), where \(p\) (the penalty parameter) is usually set to 3. This cubic relationship between the topology and the modulus is determined by the material constitutive models, and numerically, it also helps binarize the topologies, i.e., to push the optimal \({\bf x}_i\) to 1 or 0 (why?). The term \(E_{\text{min}}\) is added to provide numerical stability.
Design sensitivity analysis
Design sensitivity analysis is about computing the gradient \(\frac{df}{d{\bf x}}\), i.e., the sensitivity of the objective (compliance) with respect to the changes in the topology. This gradient represents the direction of unit topological change that will increase the compliance the most (or decrease the most if the negative gradient direction is taken). Therefore, once the gradient is derived, one can simply apply gradient ascend (or descend) to maximize (or minimize) the compliance. Analogously, knowing the gradient is the same as knowing which way to climb up (or down) the mountain.
By knowing this, one can see that design sensitivity analysis is key to all optimization problems. However, for topology optimization and many other problems, deriving the sensitivity (the gradient) is often not straight forward or in some cases very challenging. We will explain in the following why this is so and how the derivation is done in our specific case.
In general, the challenge comes from the fact that the objective \(f\) (the function we are trying to optimize) is a function of the states, which are not explicitly known without solving some governing equations. In our case, the states are the displacements \({\bf d}\) and variables are the density values \({\bf x}\). We also notice that states and variables are related through the equation \({\bf h} := {\bf K}({\bf x}) {\bf d} = {\bf u}\), which means that the states are implicitly functions of the variables. Therefore, the sensitivity \(\frac{df}{d{\bf x}}\) can be calculated as
\[\frac{df}{d{\bf x}} = (2 {\bf K}{\bf d})^T \frac{d{\bf d}}{d{\bf x}} + {\bf d}^T \frac{d{\bf K}}{d{\bf x}}{\bf d}\]The above equation requires the derivation of \(\frac{d{\bf d}}{d{\bf x}}\), which can be found by differentiating the equation \({\bf h}\):
\[\frac{d{\bf h}}{d{\bf x}} = \frac{d{\bf K}}{d{\bf x}}{\bf d} + {\bf K}\frac{d{\bf d}}{d{\bf x}} = {\bf 0}\]which leads to
\[\frac{d{\bf d}}{d{\bf x}} = {\bf K}^{-1}\frac{d{\bf K}}{d{\bf x}}{\bf d}\]Therefore
\[\frac{df}{d{\bf x}} = - {\bf d}^T \frac{d{\bf K}}{d{\bf x}}{\bf d}\]The above explains how the sensitivity is computed for our compliance minimization problem. It is worth noting that the result is only valid for (1) linear elastic material and (2) small deformation, under which the stiffness matrix \({\bf K}\) does not change during the bending of the structure and the governing equation is linear with respect to the states. In general, however, these assumptions do not hold and one will need to resort to adjoint method for computing the sensitivity. Please see this more involved but well written tutorial by Andrew Bradley.
The optimality conditions
In the above, we discussed about how to compute the design sensitivity for solving a topology optimization problem. We learned that the sensitivity (the gradient) can be treated as a force that “pushes” a current design to move towards better objective values. The question then is “when do we stop pushing?” Here is an intuitive answer: We stop when one of the two things happened: (1) when we reach a point where the force is zero; or (2) when we reach a point where there is a wall, so that the force and the “counter force” from the wall cancel out. Mathematically, the first case corresponds to a unconstrained solution (you learned this from calculus); the second case corresponds to a constrained solution, where constraints prevent us from further improving the solution.
Now consider compliance minimization. There are two kinds of constraints: One is that the density of the mesh can only go from 0 to 1; the other is that the total density (or volume) is constrained (through the volume fraction constraint). From the derived equation for sensitivity, one can see that this volume fraction constraint should always be active if an optimal topology is found, i.e., the optimal topology should have as much volume fraction as allowed (why?). From our intuitive understanding of the optimality conditions, this means that there will be a counter force from the wall through the volume fraction constraint.
This force balance, or the optimality conditions, can be expressed formally as
\[\frac{df}{d{\bf x}} + \mu \frac{d ({\bf 1}^T{\bf x}) }{d{\bf x}} = 0\]Here \({\bf 1}^T{\bf x}\) represents the total volume, thus \(\frac{d ({\bf 1}^T{\bf x}) }{d{\bf x}} = {\bf 1}\). \(-\frac{df}{d{\bf x}}\) pushes the solution towards lower compliance and \(- \mu {\bf 1}\) pushes towards lower volume. \(\mu \geq 0\) is called the Lagrangian multiplier, which measures the scale of the counter force, and is 0 when the solution does not “hit the wall”.
There are many ways to find solutions (in terms of \({\bf x}\) and \(\mu\)) to satisfy the optimality conditions. See for example the method of moving asymptotes (MMA) and augmented Lagrangian. One simple approach is to iteratively update \({\bf x}\) as
\[{\bf x}_{new} = \sqrt{-\frac{df}{d{\bf x}}/\mu}{\bf x}\]by choosing \(\mu\) in each iteration so that \({\bf x}_{new}\) is within 0 and 1. Note that the square root and the multiplication operations in the above equation are element-wise. The rationale is that from the optimality conditions, \(-\frac{df}{d{\bf x}}/\mu\) should converge to 1 at an optimal solution.
The algorithm
With these preliminaries, let us now look at the implementation. The seudo code for compliance minimization is as follows:
-
FEA setup (see details below)
-
Algorithm setup: \(\epsilon = 0.01\) (or any small positive number), \(k = 0\) (counter for the iteration), \(\Delta x =\) a number larger than \(\epsilon\)
-
While \(norm(\Delta x) \leq \epsilon\), Do:
3.1. Update the stiffness matrix \({\bf K}\) and the displacement (state) \({\bf u}\) (finite element analysis)
3.2. Calculate element-wise compliance \({\bf u}^T_i \bar{\bf K}_e {\bf u}_i\)
3.3. Calculate partial derivatives \(\frac{df}{dx_i} = - 3\Delta E x_i^2 {\bf u}^T_i \bar{\bf K}_e {\bf u}_i\)
3.4. The gradient with respect to the volume fraction constraint is a constant vector of ones (\([1,...,1]^T\))
3.5. Apply filter to \(\frac{df}{d{\bf x}}\) to smooth the gradient (See discussion below)
3.6. Update \({\bf x}\) as \({\bf x}_{new} = \sqrt{-\frac{df}{d{\bf x}}/\mu}{\bf x}\)
3.7. Update \(norm(\Delta x)\), \(k = k+1\)
Implementation details
We explain some details based on the classic 88 line topology optimization code.
The code
Some details of the template code is explained as follows:
The numbering rule for elements and nodes
The template code assumes a rectangular design domain, where each element is modeled as a unit square. The numbering of elements and nodes are explained in the figure below.
Input parameters
Inputs to the program are (1) the number of elements in the x and y directions (nelx
and nely
),
(2) the volume fraction (volfrac
, this is the number between 0 and 1 that specifies the
ratio between the volume of the target topology and the maximum volume \(nelx \times nely\)), (3) the penalty
parameter of the Young’s Modulus model (penal
, usually =3), and (4) the filter radius (rmin
,
usually =3).
Material properties
Set the Young’s Modulus (E0
), and the Poisson’s ratio (nu
). Leave Emin as a small number.
Define loadings
This line specifies the loading. Here F
is a sparse column vector with 2(nely+1)(nelx+1)
elements.
(2,1,-1,\cdots)
specifies that there is a force of -1 at the second row and first column
of the vector. According to the numbering convention of this code, this is to say that in the y direction
of the first node, there is a downward force of magnitude 1.
Define boundary conditions (Fixed DOFs)
This line specifies the nodes with fixed DOFs. [1:2:2*(nely+1)]
are x directions
of all nodes to the left side of the structure, and 2*(nelx+1)*(nely+1)
is the y direction
of the last node (right bottom corner). See figure below:
Numbering of dofs, nodes, and elements in the 88 line code.
Filtering of sensitivity (gradient)
Pure gradient descent may result in a topology with checkerboard patterns. See figure below. While mathematically sound, such a solution can be infeasible from a manufacturing perspective or too expensive to realize (e.g., through additive manufacturing of porous structures). Therefore, a smoothed solution is often more preferred.
In the code we prepare a Gaussian filter, through the following code:
The design sensitivity can then filtered by
Topology optimization with local density constraints
One drawback of the topology optimization formulation we discussed above is that the resultant topologies often have sparse structures (please test to see). In nature we observe structures that are denser and porous, e.g., bones, nests, etc, with more connecting “beams” of smaller dimensions. One of the key benefit of such structures is reliability, i.e., the failure of some beams will not drastically change the performance of the whole. Yet with sparse structures produced from our optimization, the reliability can be low.
Wu et al. recently proposed a formulation that incorporates local density constraints instead of the global volume fraction constraint. The following sample code is our implementation of Wu’s method on solving compliance problems.