1 Introduction

Lighter designs are desirable in many industrial applications and structural optimization is an effective way to generate light weight structures. Topology optimization (Bendsøe and Sigmund 2003) is the first structural optimization stage, it is used for conceptual design, and thus the stage where the greatest mass reduction can be achieved. In topology optimization no initial design is required; instead the design variables, which are scale factors of elemental properties, determine whether an element should be part of a structural member or a hole.

In the traditional topology optimization formulation, stiffness is maximized for a prescribed amount of material. Traditionally optimized designs often contain high stress concentrations and as will be shown, sometimes even geometrical shapes causing stress singularities. Major manual adjustments or shape optimization is therefore needed in order to fulfill engineering requirements such as stress constraints. The changes required to the topology are often severe, and topology optimization is thus used more as a help to find optimal load paths rather than to achieve a conceptual design. In this paper, stress constraints are introduced already in the topology optimization stage, this allows for more sophisticated designs that appear more like final designs than those obtained from the traditional formulation. Stress constraints in topology optimization therefore allow for a greater weight saving and simplify the subsequent design work.

We consider linear elastic isotropic materials and are only interested in so-called black-and-white designs, i.e. only solid material and holes are allowed in the final design. This simplifies the interpretation and allows 3D structures to be evaluated in future work. Even though the final design strives for the integer values 1 (black) and 0 (white), we use continuous design variables and Solid Isotropic Material with Penalization (SIMP) to achieve a black-and-white design by penalizing intermediate design variable values. SIMP was initially introduced by Bendsøe (1989) and the name was later suggested by Rozvany et al. (1992). A similar formulation is also used to penalize stresses, as described in Le et al. (2010) and shown in Section 4 in this paper.

A design variable filter (Bruns and Tortorelli 2001) is used to remove mesh dependency and the checkerboard phenomenon. The filter also forces a minimum width of the structural members, thus avoiding artificial stiffness that occurs for members that are only one or two elements wide.

Our aim in using stress constraints in topology optimization is not to perfectly control the stress level but to avoid high stress concentrations, and thus generate a design that does not have to undergo severe modifications in order to be developed into a final design that fulfills the stress requirements. Topology optimization is a conceptual design tool that requires post-processing and further analysis, but the goal is that the subsequent design work should be more straightforward, as it is done from a better starting point.

Criteria based on stress are among the most important ones for engineering purposes and have thus been discussed since the very beginning of topology optimization. The paper by Bendsøe and Kikuchi (1988), which is considered to be the origin of topology optimization, mentions stress constraints even though these are not used in the formulation. In addition, stress constraints were earlier used in optimization of trusses by Dorn et al. (1964). In recent years, stress constraints have received attention from Svanberg and Werme (2007), Le et al. (2010) and París et al. (2009) among others. It is noted that, compared to the traditional stiffness maximization problem, additional difficulties occur: Sved and Ginos (1968) found that stress constraints are violated as the bar area goes to zero in a truss optimization problem and the bar can thus not be removed (known as singularity). The singularity problem is also present in 2D and 3D problems where non-disappearing stresses remain as the design variables go towards zero. A region with low design variable values can still have a strain which give rise to a stress with a nonzero and sometimes remarkably high value, when it actually should be zero as it represents a hole. The singularity problem is discussed in many papers, such as Guo et al. (2001), Kirsch (1990), Rozvany and Birker (1994) among others, and one way to avoid it is to use an \(\epsilon \)-relaxation approach as suggested by Cheng and Guo (1997) and as is used in stress constrained problems by Duysinx and Bendsøe (1998) and Duysinx and Sigmund (1998). We use a stress penalization introduced by Bruggi (2008), that besides giving further penalization of intermediate design variables also avoids the singularity problem. A simple example showing the singularity problem is considered in Duysinx and Bendsøe (1998). Figure 1 shows this example treated using our method, no singularity problem is encountered and a hole is created between the two bars, a result which was not possible without \(\epsilon \)-relaxation in the stress formulation used in Duysinx and Bendsøe (1998).

Fig. 1
figure 1

Simple example used in Duysinx and Bendsøe (1998)

Duysinx and Bendsøe (1998) also discuss a problem caused by the high number of local stress constraints that are needed due to the fact that stress is a local measure: the problem becomes computationally expensive and requires efficient methods to handle the computational effort. Duysinx and Sigmund (1998) introduced a global stress measure using a similar formulation, but where all stresses are grouped into one stress constraint. The global stress measure reduces the computational time considerably. However, the local stress control is low and in some cases not acceptable. Due to these drawbacks, we are not particulary interested in either the local or the global approach to stress constraints. Instead, we use a clustered approach where a moderate number of stress constraints are used and several stress evaluation points are clustered into each constraint, in a way somewhat similar to the block aggregation in París et al. (2010) or the regional stress measure in Le et al. (2010).

We also note that stress constrained topology problems have been solved using the level set approach by e.g. Allaire and Jouve (2008), Amstutz and Novotny (2010) and Guo et al. (2011). In the level set approach two phases, typically representing solid material or voids, are used and as the stress constraints only are applied to the solid phase, no singularity problems occur. The final designs are also free from the transition layer of intermediate design variable values between solid and voids that remain for filtered SIMP-based formulations. However, the large number of design variables remain and a global stress measure that approximates local stresses (Allaire and Jouve 2008; Amstutz and Novotny 2010), or an active set strategy (Guo et al. 2011) is used in order to reduce the computational cost.

We use bilinear quadrilateral elements which, despite their drawbacks, see e.g. Cook et al. (2002), are very common in topology optimization problems. The element is not particulary well suited for stress analysis, but we use it in this paper due to its simplicity, low computational cost and as it has been used earlier in stress based problems in e.g. Le et al. (2010), with promising results. The stress is evaluated in the centroid of the element, which corresponds to the superconvergent stress point. The problem and the sensitivity analysis are formulated generally, so that different element types can be considered in future work.

We also mention that the final optimization problem is solved by the Method of Moving Asymptotes (MMA) (Svanberg 1987).

The paper is organized as follows: Section 2 describes the problem formulations. The design variable filter and penalization techniques are discussed in Sections 3 and 4 respectively. Section 5 presents the stress measure used for the clustered approach and different clustering techniques are discussed in Section 6. Calculation of the gradients involved is done in Section 7 and a review of modeling aspects is found in Section 8. In Section 9 we show the numerical results and conclusions are drawn in Section 10.

2 Problem formulations

We optimize structures that are discretized by the Finite Element Method (FEM) (Hughes 1987). The design variables are collected in a vector \(\boldsymbol {x}\) and are scale factors of the elemental properties, i.e. there is one design variable connected to each finite element that is included in the optimization. Different interpretations of the design variables: such as thickness, porosity or as describing a composite material, are common in the literature, but we prefer to see them as mathematical scale factors without physical interpretation. The optimization strives for a final design where the scale factor is zero or one, so there is no need for a physical interpretation of the intermediate design variable values. Section 4 describes how such final designs are achieved. The design variables \(\boldsymbol {x}\) are filtered, see Section 3, which relates \(\boldsymbol {x}\) to the variables \(\boldsymbol {\rho }\), i.e. \(\boldsymbol {\rho }=\boldsymbol {\rho }(\boldsymbol {x})\). The latter variables will be called the filtered variables and they are considered to be physical variables, as they define the stiffness and enter the mass calculation. The equilibrium equation for a design \(\boldsymbol {\rho }(\boldsymbol {x})\) becomes

$$ \boldsymbol{K}(\boldsymbol{\rho}\left(\boldsymbol{x})\right) \boldsymbol{u}=\boldsymbol{F}, $$
(1)

where \(\boldsymbol {K}(\boldsymbol {\rho }\left (\boldsymbol {x})\right )\) is the global stiffness matrix of the structure, \(\boldsymbol {u}\) is the vector of global nodal displacements and \(\boldsymbol {F}\) is a vector of known external loads.

We use a nested formulation, i.e. the equilibrium equation (1) is not used as a constraint as in the simultaneous formulation described by e.g. Bendsøe et al. (1994). Instead, the displacement vector is seen as a given function of the design variables and it is solved for in the finite element analysis. For a given design \(\boldsymbol {\rho }(\boldsymbol {x})\) and for an invertible stiffness matrix, the displacement vector as a function of \(\boldsymbol {x}\) reads,

$$\boldsymbol{u}=\boldsymbol{u}(\boldsymbol{x})=\boldsymbol{K}^{-1}(\boldsymbol{\rho}\left(\boldsymbol{x})\right)\boldsymbol{F}. $$

Three different formulations are discussed and compared in this paper. The first formulation, in which the mass is minimized subjected to stress constraints, is our main concern. It reads,

$$(\mathbb{P}_1) \quad \left\{ \begin{array}{l} \displaystyle \min\limits_{\boldsymbol{x}} \sum\limits_{e=1}^{n_e}{m_e \rho_e(\boldsymbol{x})} \\ [14pt] \mbox{s.t.} \left \{ \begin{array}{l} \displaystyle \sigma_i^{PN} (\boldsymbol{x}) \leq \overline{\sigma}, \; i=1,..,n_c \\ [4pt] \displaystyle \underline{x}_e\leq x_e\leq\overline{x}_e, \; e=1,..,n_e, \end{array}\right. \end{array}\right. $$

where \(n_e\) is the number of design variables and \(m_e\) is the solid element mass for the element related to design variable \(e\). The \(e\):th filtered variable is denoted \(\rho _e(\boldsymbol {x})\) and \(x_e\) is the \(e\):th design variable, limited by the box constraint limits \(\overline {x}_e=1\) and \(\underline {x}_e=\epsilon \), where \(\epsilon \) is a small positive number used to avoid the stiffness matrix becoming singular. The stress measure used in this paper is a modified P-norm based on von Mises stresses, which for cluster number \(i\) is denoted \(\sigma _i^{PN}(\boldsymbol {x})\) and which is discussed in Section 5. The number of clusters, or equally, the number of stress constraints, is denoted \(n_c\) and \(\overline {\sigma }\) is the stress limit. We note that stress measures other than von Mises could be used and that formulations similar to \((\mathbb {P}_1)\) have been used in Duysinx and Bendsøe (1998), Le et al. (2010) and París et al. (2009) among others, where, however, the stress measure is formulated differently.

In the second formulation we replace the mass objective function with a compliance objective, i.e. the optimization strives for the stiffest design. This objective requires a limit on the available volume or mass that can be distributed inside the design domain. We here choose to constrain the available mass so that the comparison with formulation \((\mathbb {P}_1)\) is straightforward. To the authors’ knowledge, this formulation has previously only been used by Werme (2008), who used it with a discrete approach developed by Svanberg and Werme (2007). This second formulation reads

$$(\mathbb{P}_2) \quad \left\{ \begin{array}{l} \displaystyle \min\limits_{\boldsymbol{x}} \frac{1}{2} \boldsymbol{F}^T \boldsymbol{u} (\boldsymbol{x}) \\ [12pt] \mbox{s.t.} \left \{ \begin{array}{l} \displaystyle \sigma_i^{PN}(\boldsymbol{x}) \leq \overline{\sigma}, \; i=1,..,n_c \\ [6pt] \displaystyle \sum\limits_{e=1}^{n_e} {m_e \rho_e(\boldsymbol{x})} \leq \overline{M} \\ [13pt] \displaystyle \underline{x}_e \leq x_e \leq \overline{x}_e, \; e=1,..,n_e, \end{array}\right. \end{array}\right. $$

where \(\overline {M}\) is the allowable total mass.

The third problem is the traditional stiffness based formulation that in this paper is used only for comparison. In this formulation, the compliance is minimized subjected to a mass constraint, see Bendsøe and Sigmund (2003) and the references therein for an overview of important papers based on this formulation, that reads

$$(\mathbb{P}_3) \quad \left\{ \begin{array}{l} \displaystyle \min\limits_{\boldsymbol{x}} \frac{1}{2} \boldsymbol{F}^T \boldsymbol{u} (\boldsymbol{x}) \\ [12pt] \mbox{s.t.} \left \{ \begin{array}{l} \displaystyle \sum\limits_{e=1}^{n_e} {m_e \rho_e (\boldsymbol{x})} \leq \overline{M} \\ [11pt] \displaystyle \underline{x}_e \leq x_e \leq \overline{x}_e, \; e=1,..,n_e. \end{array} \right. \end{array}\right. $$

3 Filtering of design variables

A design variable filter (Bruns and Tortorelli 2001) is used, i.e. filtered variables \(\boldsymbol {\rho }\) are created by taking a weighted average of neighboring design variables \(x_{j}\). The filtered variables \(\boldsymbol {\rho }\) are considered as physical variables in the sense that they enter the calculation of the stiffness matrix and the mass, whereas \(\boldsymbol {x}\) have no physical interpretation. The design variable filter reads

$$\rho_{e}(\boldsymbol{x})=\frac{\underset{j\in\Omega_{e}}{\sum}w_{j}x_j}{\underset{j\in\Omega_{e}}{\sum}w_j}, $$

where \(\Omega _{e}\) is the set of design variable indices related to elemental centroids within the filter radius \(r_{0}\), measured from the centroid of the element related to design variable \(e\), as visualized in Fig. 2. The weight factor \(w_j\) is here defined by a cone, i.e. the weight is decreased linearly with \(r_j\), which is the distance between the centroids of the elements related to design variable \(j\) and \(e\), i.e.

$$w_{j}=\frac{r_{0}-r_j}{r_{0}}. $$

Note that the weight is zero for all design variables that are excluded from the set \(\Omega _e\). From an implementation point of view, a matrix \(\boldsymbol {W}\) that includes the weights is created such that

$$ \rho_{e}(\boldsymbol{x})=\underset{j=1}{\overset{n_e}{\sum}}W_{ej}x_{j}. $$
(2)
Fig. 2
figure 2

Visualization of the design variable filter

4 Penalization

In order to create black-and-white structures, a penalization function is introduced that makes intermediate design variable values disproportionately expensive. In this paper, we strive for black-and-white designs and SIMP is used to penalize the stiffness for intermediate design variable values and a similar penalization is used to penalize stresses.

4.1 Stiffness penalization

The SIMP penalization function, \(\eta _K(\rho _e(\boldsymbol {x}))\) is inserted when the global stiffness matrix \(\boldsymbol {K}(\boldsymbol {\rho }\left (\boldsymbol {x})\right )\) is assembled from the solid material element stiffness matrices \(\boldsymbol {\hat {K}}_e\) as

$$\boldsymbol{K}(\boldsymbol{\rho}\left(\boldsymbol{x})\right)=\underset{e=1}{\overset{n_e}{\sum}} \eta_K(\rho_e(\boldsymbol{x})) \boldsymbol{\hat{K}}_e. $$

The SIMP penalization function is given by

$$\eta_K(\rho_e(\boldsymbol{x}))=( \rho_e (\boldsymbol{x}) )^q, $$

where \(q>1\) is a penalization factor that, in this paper, is set to \(q=3\), which several authors have proven to work well.

4.2 Stress penalization

The solid material stress vector at stress evaluation point \(a\) is written in Voigt notation as

$$\hat{\boldsymbol{\sigma}}_a(\boldsymbol{x})= \left(\begin{array}{cccccc} \hat{\sigma}_{ax} & \hat{\sigma}_{ay} & \hat{\sigma}_{az} & \hat{\tau}_{axy} & \hat{\tau}_{ayz} & \hat{\tau}_{azx}\end{array}\right)^{T}. $$

It is calculated in the finite element analysis as

$$\hat{\boldsymbol{\sigma}}_a(\boldsymbol{x})=\boldsymbol{E}\boldsymbol{B}_a\boldsymbol{u}(\boldsymbol{x}), $$

where \(\boldsymbol {E}\) is the constitutive matrix and \(\boldsymbol {B}_a\) is the strain-displacement matrix corresponding to stress evaluation point \(a\). The solid material stresses are also penalized for intermediate design variable values, giving the penalized stress measure \(\boldsymbol {\sigma }_a(\boldsymbol {x})\), as

$$ \boldsymbol{\sigma}_a(\boldsymbol{x})=\eta_S(\rho_e(\boldsymbol{x}))\hat{\boldsymbol{\sigma}}_a(\boldsymbol{x}), $$
(3)

where \(\rho _e(\boldsymbol {x})\) is the filtered variable corresponding to the element to which stress evaluation point \(a\) belongs. The stress penalization \(\eta _S(\rho _e(\boldsymbol {x}))\) is constructed such that \(\boldsymbol {\sigma }_a(\boldsymbol {x})\) is increased for intermediate design variable values, thus making the intermediate values unproportionately expensive. Our experience points towards that the stress penalization

$$ \eta_S(\rho_e(\boldsymbol{x}))=(\rho_e(\boldsymbol{x}) )^{\frac{1}{2}}, $$
(4)

works well. This penalization (4) represents the penalization in Bruggi (2008), but with a specific choice of the exponent, as suggested in Le et al. (2010).

Compared to the stress calculation by e.g. Duysinx and Bendsøe (1998), this stress penalization (4) gives a stress that is non-physical for intermediate design variable values. However, we strive for black-and-white designs and the stress penalization is such that \(\boldsymbol {\sigma }_a\) and \(\hat {\boldsymbol {\sigma }}_a\) coincide for \(\rho _e=1\) and

$$\underset{\rho_e \rightarrow 0}{\lim} \boldsymbol{\sigma}_a(\boldsymbol{x})=\boldsymbol{0}, $$

where the latter is the reason why we do not experience singularity problems. The same observation was recently made by Kočvara and Stingl (2012), who use a stress formulation with the same properties.

5 Stress measure

The von Mises stress measure is often used for dimensioning statically loaded structures such as those that are considered in this paper. It is therefore used as stress measure in the optimization. The penalized von Mises stress in stress evaluation point \(a\), \(\sigma _a^{vM}(\boldsymbol {x})\), is a function of the corresponding penalized stress vector (3), given by

$$\begin{array}{lll} \sigma_a^{vM}(\boldsymbol{x})&=&\left(\sigma_{ax}^2+\sigma_{ay}^2+\sigma_{az}^2-\sigma_{ax}\sigma_{ay}-\sigma_{ay}\sigma_{az}\right.\\ &&\;\;\left.-\,\sigma_{az}\sigma_{ax}+3\tau_{axy}^2+3\tau_{ayz}^2+3\tau_{azx}^2\right)^{\frac{1}{2}}. \end{array} $$
(5)

Three different approaches to stress constraints are discussed: local, global and clustered. The local and global approaches (Duysinx and Bendsøe 1998; Duysinx and Sigmund 1998), mean that either one constraint is applied to each stress evaluation point in the model (local) or that only one stress constraint is applied to the entire model (global). However, neither of these two approaches are useful in practice; the local approach becomes too expensive and the global approach is too rough. Therefore, we use a clustered approach (París et al. 2010; Le et al. 2010), where stress evaluation points are sorted into clusters, and one stress constraint is applied to each cluster. This allows for a trade-off between how well the stress is controlled and the computational cost. Our experience is that, even with a small number of stress constraints, it is possible to avoid geometrical shapes that cause stress singularities and, to some extent, also stress concentrations. How the stress evaluation points are sorted into clusters and how these are updated is discussed in Section 6, where it also is noted that the local and the global approach can be seen as special cases of the clustered approach.

In order to create the clustered stress measure used in formulation \((\mathbb {P}_1)\) and \((\mathbb {P}_2)\), stresses from several stress evaluation points are clustered and used to calculate a single stress measure using a modified P-norm. This has been done in a somewhat similar way before in Yang and Chen (1996), Le et al. (2010) and Duysinx and Sigmund (1998), but our modification is different as will be discussed below. The P-norm stress measure for cluster \(i\), \(\sigma _i^{PN}(\boldsymbol {x})\), reads

$$ \sigma^{PN}_i(\boldsymbol{x})= \left(\frac{1}{N_i} \underset{a\in \Omega_i}{\sum} \left( \sigma_a^{vM} (\boldsymbol{x}) \right)^p \right)^{\frac{1}{p}}, $$
(6)

where \(p\) is the P-norm factor and \(\Omega _i\) is the set of stress evaluation points in cluster \(i\). The sum is divided by \(N_i\), which is the number of stress evaluation points in \(\Omega _i\). Thus, if all stresses are the same, i.e. \(\sigma _a^{vM}(\boldsymbol {x})=\sigma ^{vM}\), then

$$\begin{array}{lll} \sigma^{PN}_i(\boldsymbol{x}) &= & \left(\frac{1}{N_i} \underset{a\in \Omega_i}{\sum} \left( \sigma_a^{vM} (\boldsymbol{x}) \right)^p \right)^{\frac{1}{p}} \\ & =& \left(\frac{1}{N_i}\right)^{\frac{1}{p}} \left(N_i \left( \sigma^{vM} \right)^p \right)^{\frac{1}{p}}= \sigma^{vM}, \end{array} $$
(7)

i.e. the P-norm measure represents the local stresses exactly. In all other cases \(\sigma ^{PN}_i(\boldsymbol {x})\) in (6) will underestimate the maximum local stress, which is shown by Duysinx and Sigmund (1998) where the expression that is used is similar to (6), except for the clustered approach and the \(\epsilon \)-relaxation. In Duysinx and Sigmund (1998) it is also proved that the choice \(N_i=1\) gives an expression that always has a value above the maximum stress. These two results are summarized as follows:

$$\begin{array}{lll} \left(\frac{1}{N_i} \underset{a\in \Omega_i}{\sum} \left( \sigma_a^{vM} (\boldsymbol{x}) \right)^p \right)^{\frac{1}{p}} &\leq& \max\limits_{a\in \Omega_i} \sigma_a^{vM} (\boldsymbol{x}) \\ &\leq& \left(\underset{a\in \Omega_i}{\sum} \left( \sigma_a^{vM} (\boldsymbol{x}) \right)^p \right)^{\frac{1}{p}}. \end{array} $$

Since the stress constraint in \((\mathbb {P}_1)\) and \((\mathbb {P}_2)\) can be written as

$$\left(\underset{a\in \Omega_i}{\sum} \left( \sigma_a^{vM} (\boldsymbol{x}) \right)^p \right)^{\frac{1}{p}} \leq N_i^{\frac{1}{p}}\overline{\sigma}, $$

we conclude that the maximum local stress in the structure is below \(N_i^{1/p}\overline {\sigma }\). However, if we create the clusters such that the case shown in (7) is approached, then we also approach \(\sigma ^{vM}\leq \overline {\sigma }\), as is desired. On the other hand, the \(1/N_i\)-term has the positive effect that it acts like a built-in scaling of the limit value which proves to be beneficial for convergence of the optimization problems. In particular, it avoids problems in the first iterations where some points can have very high stresses due to initial geometrical shapes causing stress singularities.

Stresses in the optimized structure will locally become higher than the stress limit, but as mentioned before, in this conceptual design phase we allow some stress peaks as long as the geometrical shape is such that stress singularities are avoided and the stress peaks easily can be removed.

We also note that Le et al. (2010) use an elemental scale factor based on the volume of element \(a\), instead of the \(1/N_i\)-term in (6). From the discussion above, we see that the discretization thus influences the local stresses as the stress can then be higher in a smaller element than in a larger. In order to get the P-norm value closer to the maximum local stress, Le et al. scale the current values with respect to stress values from the previous iteration. This approach could also be used in our formulation, however, if the clusters are created as described in Section 6, a good stress control can be achieved in either case.

Increasing the value of the exponent \(p\) in (6) brings the P-norm value closer to the maximum stress in each cluster. Applying the limit value shown in Duysinx and Sigmund (1998) one finds that

$$\underset{p \rightarrow \infty}{\lim} \left(\frac{1}{N_i} \underset{a\in \Omega_i}{\sum} \left( \sigma_a^{vM} (\boldsymbol{x}) \right)^p \right)^{\frac{1}{p}}= \underset{a\in \Omega_i}{\mbox{max}} \, \sigma_a^{vM}(\boldsymbol{x}). $$

However, numerical problems are unfortunately experienced for too high values of \(p\). On the other extreme, \(p=1\) gives the mean stress for each cluster. Different \(p\)-values are evaluated in Le et al. (2010) and a discussion is also found in Duysinx and Sigmund (1998). On the basis of those papers and our own tests we use \(p=8\) in the numerical examples.

Depending on the value of the stress constraint and the \(p\)-value, problems with the numerical accuracy can also occur because \(( \sigma _a^{vM}(\boldsymbol {x}) )^p\) in (6) becomes very large. One solution is then to normalize \(\sigma _a^{vM}(\boldsymbol {x})\) with \(\overline {\sigma }\), which gives a mathematically equivalent formulation. The stress constraint \(\sigma _i^{PN}(\boldsymbol {x}) \leq \overline {\sigma }\) in problem formulation \((\mathbb {P}_1)\) and \((\mathbb {P}_2)\) is thus replaced by

$$\left(\frac{1}{N_i} \underset{a\in \Omega_i}{\sum} \left( \frac{\sigma_a^{vM} (\boldsymbol{x})}{\overline{\sigma}} \right)^p \right)^{\frac{1}{p}} \leq 1. $$

6 Distribution of points into clusters

The main reason for using clusters is to reduce the \(n_e\) number of constraints in the local approach to \(n_c\ll n_e\) clustered constraints and still maintain the possibility to control the local stress. The number of clusters, \(n_c\), greatly effects to which extent the local stresses are constrained. We may think of the two extremes \(n_c=1\) and \(n_c=n_e\), which brings us back to the global and local approaches, respectively.

The P-norm (6) that is used to cluster stresses from multiple stress evaluation points to one constraint takes the stress to the power of a factor \(p\). Consequently, a local high stress can raise the P-norm value, even though there might have been low stresses in the other evaluation points. On the other hand, due to the \(1/N_i\)-term the P-norm value will be lower than the maximum local stress. Obviously, the problem is influenced by how the clusters are created, i.e. which evaluation points that belong to the set \(\Omega _i\). Here we present two techniques for how the evaluation points are sorted into clusters: the Stress level approach and the Distributed stress approach, as described later in this section.

The distribution of the stress evaluation points in the clusters might have to be updated during the iterations in order for \(\sigma ^{PN}_i(\boldsymbol {x})\) to be a good approximation to the local stresses. However, changing the distribution of evaluation points within the clusters implies that the problem is changed. Thus, different (but similar) problems are solved in successive iterations and we are thus solving a series of related problems. We note that MMA uses the design variables from the two previous iterations in order to determine the move limits, see Svanberg (1987) for details. In the case when clusters are updated, the design variables in the current iteration are found by solving a problem that is slightly different than the problem for which the previous variables were found, and this could cause the move limits to be either too conservative or too aggressive. However, we still obtain convergence to a feasible design and have not noticed any problems as a result of this issue.

6.1 Stress level technique

In the stress level clustering technique, stress evaluation points that have a similar stress level are clustered together. This method gives a large variation of the different \(\sigma ^{PN}_i(\boldsymbol {x})\)-values but the stresses in the evaluation points within each cluster are as close to each other as possible. The P-norm measure becomes a good approximation of the cluster member stresses, because we are approaching the case shown in (7). Another positive effect is that in many problems the stress constraint for the low-level clusters eventually becomes inactive.

The clusters are organized according to the scheme shown in (8). The stress evaluation points are sorted in descending order based on their stress level, and the \(n_e/n_c\) first points create cluster 1, the next \(n_e/n_c\) points create cluster 2 etc. That is, we have the same number of points within all clusters with the exception of the last cluster which may contain fewer points. The clustering scheme reads

$$\begin{array}{lll} \underbrace{\sigma_{1} \geq \sigma_{2} \geq \sigma_{3} \geq ..... \geq \sigma_{\frac{n_e}{n_c}}}_{\mbox{cluster}\,1} &\geq& \underbrace{..... \geq \sigma_{\frac{2n_e}{n_c}}}_{\mbox{cluster}\,2} \geq ..... \\ &\geq& \sigma_{\frac{(n_c-1)n_e}{n_c}} \geq \underbrace{..... \geq \sigma_{n_e}}_{\mbox{cluster}\, n_c}. \end{array} $$
(8)

6.2 Distributed stress technique

In the distributed stress technique, each cluster contains stress evaluation points with stresses that span the whole stress range. Thus, each cluster obtains approximately the same stress value. The motivation for this technique is that it is expected to allow for easier convergence, as high local stresses are damped by a presumably large number of low local stresses. The clustered stress measure in (6) will thus be lower than if the stress level technique is used.

Again, the stress evaluation points are sorted in descending order based on their stress. The first point is then inserted into cluster 1, the second into cluster 2 etc., until the \(\frac {n_e}{n_c}\):th point is reached. The cluster counter is then reset and restarted from 1. This method is the same as in Le et al. (2010) when the clusters are updated every iteration. The formulation looks like

$$\begin{array}{lll} \underbrace{\sigma_{1}}_{\mbox{cluster}\,1} &\geq& \underbrace{\sigma_{2}}_{\mbox{cluster}\,2} \geq ..... \geq \underbrace{\sigma_{\frac{n_e}{n_c}-1}}_{\mbox{cluster}\,(n_c-1)}\\ &\geq&\underbrace{\sigma_{\frac{n_e}{n_c}}}_{\mbox{cluster}\, n_c} \geq \underbrace{\sigma_{\frac{n_e}{n_c}+1}}_{\mbox{cluster}\,1} \geq .....\underbrace{ \geq \sigma_{n_e}}_{\mbox{cluster}\, n_c}. \end{array}$$

7 Sensitivity analysis

The Method of Moving Asymptotes (Svanberg 1987) that is used to solve the optimization problem requires first order sensitivity information of the constraints and the objective function. The gradient of the mass objective, \(f_0\), in \((\mathbb {P}_1)\) is

$$ \frac{\partial{f_0}}{\partial{x_b}}=\sum\limits_{e=1}^{n_e}{m_e \frac{\partial{\rho_e(\boldsymbol{x})}}{\partial{x_b}}}= \sum\limits_{e=1}^{n_e}{m_e W_{eb}}, $$
(9)

where \(W_{eb}\) are the filter weights defined in (2). We note that the gradient of the mass is affected by neighboring design variables through the filter. However, for the numerical examples in this paper, where every element has the same size and material, all solid element masses are equal, i.e., \(m_e=m\), and we find that (9) can be written

$$\frac{\partial{f_0}}{\partial{x_b}}= \sum\limits_{e=1}^{n_e}{m_e W_{eb}}= m \sum\limits_{e=1}^{n_e}{W_{eb}}=m, $$

which holds true as

$$\underset{e=1}{\overset{n_e}{\sum}}W_{eb}=1. $$

The compliance objective, \({C}=\frac {1}{2}\boldsymbol {F}^T\boldsymbol {u}(\boldsymbol {x})\), in \((\mathbb {P}_2)\) and \((\mathbb {P}_3)\) has a well known self adjoint gradient:

$$\frac{\partial{{C}(\boldsymbol{x})}}{\partial{x_b}}=-\frac{1}{2} \boldsymbol{u}^T(\boldsymbol{x}) \frac{\partial \boldsymbol{K}(\boldsymbol{\rho}\left(\boldsymbol{x})\right)}{\partial x_b}\boldsymbol{u}(\boldsymbol{x}), $$

see e.g. Christensen and Klarbring (2008) for details.

The stress constraints are the P-norm stresses in (6), and the gradients follow from the chain rule:

$$\begin{array}{lll} \frac{\partial \sigma^{PN}_i(\boldsymbol{x})}{\partial x_b}&= & \underset{a\in \Omega_i}{\sum}\frac{\partial \sigma^{PN}_i(\boldsymbol{x})}{\partial \sigma^{vM}_a} \frac{\partial \sigma^{vM}_a(\boldsymbol{x})}{\partial x_b} \\ &= & \underset{a\in \Omega_i}{\sum}\frac{\partial \sigma^{PN}_i(\boldsymbol{x})}{\partial \sigma^{vM}_a} \left( \frac{\partial \sigma^{vM}_a(\boldsymbol{x})}{\partial \boldsymbol{\sigma}_{a}} \right)^T \frac{\partial \boldsymbol{\sigma}_{a}(\boldsymbol{x})}{\partial x_b}. \end{array} $$
(10)

The derivatives in (10) are calculated in the following subsections.

7.1 Derivative of the P-norm w.r.t. the von Mises stress

The \(\partial \sigma _i^{PN}(\boldsymbol {x}) / \partial \sigma _a^{vM}\) term in (10) is determined by taking the derivative of (6) as

$$\begin{array}{lll} \frac{\partial \sigma_i^{PN}(\boldsymbol{x})}{\partial \sigma_a^{vM}} &=&\frac{1}{p}\left(\frac{1}{N_i} \underset{a\in \Omega_i}{\sum} \left(\sigma_a^{vM}(\boldsymbol{x})\right)^{p}\right)^{\left(\frac{1}{p}-1\right)}\\ &&\times\,\frac{1}{N_i} p \left(\sigma_a^{vM}(\boldsymbol{x})\right)^{p-1} \\ &=&\left(\frac{1}{N_i} \underset{a\in \Omega_i}{\sum} \left(\sigma_a^{vM}(\boldsymbol{x})\right)^{p}\right)^{\left(\frac{1}{p}-1\right)}\\ &&\times\,\frac{1}{N_i} \left(\sigma_a^{vM}(\boldsymbol{x})\right)^{p-1}. \end{array}$$

7.2 Derivative of the von Mises stress w.r.t. the stress components

The derivatives of the von Mises stress (5) with respect to its stress components are

$$\frac{\partial \sigma_a^{vM}(\boldsymbol{x})}{\partial\sigma_{ax}} =\frac{1}{2\sigma_a^{vM}(\boldsymbol{x})}\left(2\sigma_{ax}(\boldsymbol{x}) -\sigma_{ay}(\boldsymbol{x})-\sigma_{az}(\boldsymbol{x})\right) $$
$$\frac{\partial \sigma_a^{vM}(\boldsymbol{x})}{\partial\sigma_{ay}} =\frac{1}{2\sigma_a^{vM}(\boldsymbol{x})}\left(2\sigma_{ay}(\boldsymbol{x}) -\sigma_{ax}(\boldsymbol{x})-\sigma_{az}(\boldsymbol{x})\right) $$
$$\frac{\partial \sigma_a^{vM}(\boldsymbol{x})}{\partial\sigma_{az}} =\frac{1}{2\sigma_a^{vM}(\boldsymbol{x})}\left(2\sigma_{az}(\boldsymbol{x}) -\sigma_{ax}(\boldsymbol{x})-\sigma_{ay}(\boldsymbol{x})\right) $$
$$\frac{\partial \sigma_a^{vM}(\boldsymbol{x})}{\partial\tau_{axy}} =\frac{3}{\sigma_a^{vM}(\boldsymbol{x})}\tau_{axy}(\boldsymbol{x}) $$
$$\frac{\partial \sigma_a^{vM}(\boldsymbol{x})}{\partial\tau_{ayz}} =\frac{3}{\sigma_a^{vM}(\boldsymbol{x})}\tau_{ayz}(\boldsymbol{x}) $$
$$\frac{\partial \sigma_a^{vM}(\boldsymbol{x})}{\partial\tau_{azx}} =\frac{3}{\sigma_a^{vM}(\boldsymbol{x})}\tau_{azx}(\boldsymbol{x}). $$

7.3 Derivative of the stress components w.r.t. the design variable

The derivative of the penalized stress vector (3) with respect to design variable \(x_b\) reads:

$$\begin{array}{lll} \frac{\partial\boldsymbol{\sigma}_a(\boldsymbol{x})}{\partial x_b} &=& \underset{r=1}{\overset{n_a}{\sum}}\frac{\partial\boldsymbol{\sigma}_a}{\partial \rho_r}\frac{\partial\rho_r(\boldsymbol{x})}{\partial x_b}\\ &=& \underset{r=1}{\overset{n_a}{\sum}}\frac{\partial\eta_S(\rho_e(\boldsymbol{x}))}{\partial\rho_r}\frac{\partial\rho_r(\boldsymbol{x})}{\partial x_b} \boldsymbol{E}\boldsymbol{B}_a\boldsymbol{u}(\boldsymbol{x}) \\ &&+\, \eta_S(\rho_e(\boldsymbol{x}))\boldsymbol{E}\boldsymbol{B}_a \frac{\partial\boldsymbol{u}(\boldsymbol{x})}{\partial x_b}, \end{array} $$
(11)

where \(n_a\) is the total number of stress evaluation points and \(\partial \eta _S(\rho _e(\boldsymbol {x})) / \partial \rho _r \neq 0\) only for \(r=e\), when the penalization in (4) is used. Thus, the sum can be removed and (11) becomes

$$\begin{array}{lll} \frac{\partial\boldsymbol{\sigma}_a(\boldsymbol{x})}{\partial x_b} &=& \frac{\partial\eta_S(\rho_e(\boldsymbol{x}))}{\partial\rho_e}\frac{\partial\rho_e(\boldsymbol{x})}{\partial x_b} \boldsymbol{E}\boldsymbol{B}_a\boldsymbol{u}(\boldsymbol{x}) \\ &&+\,\eta_S(\rho_e(\boldsymbol{x}))\boldsymbol{E}\boldsymbol{B}_a \frac{\partial\boldsymbol{u}(\boldsymbol{x})}{\partial x_b}. \end{array} $$
(12)

7.4 Adjoint method

In this problem, the number of design variables \(\boldsymbol {x}\) will be large, but the number of constraints can be kept moderate due to the clusters. Therefore, the adjoint method is preferable for solving (10). The term \(\partial \boldsymbol {u}(\boldsymbol {x}) / \partial x_b\) in (12) is calculated from the global state equation (1). By the chain rule we get

$$\underset{r=1}{\overset{n_e}{\sum}} \frac{\partial\boldsymbol{K}(\boldsymbol{\rho}\left(\boldsymbol{x})\right)}{\partial\rho_r}\frac{\partial\rho_r(\boldsymbol{x})}{\partial x_b}\boldsymbol{u}(\boldsymbol{x}) + \boldsymbol{K}(\boldsymbol{\rho}\left(\boldsymbol{x})\right) \frac{\partial\boldsymbol{u}(\boldsymbol{x})}{\partial x_b}=0, $$

from which \(\partial \boldsymbol {u}(\boldsymbol {x}) / \partial x_b\) can be obtained:

$$ \frac{\partial\boldsymbol{u}(\boldsymbol{x})}{\partial x_b} = - \boldsymbol{K}^{-1}(\boldsymbol{\rho}\left(\boldsymbol{x})\right)\left[\underset{r=1}{\overset{n_e}{\sum}}\frac{\partial\boldsymbol{K}(\boldsymbol{\rho}\left(\boldsymbol{x})\right)}{\partial\rho_r} \frac{\partial\rho_r(\boldsymbol{x})}{\partial x_b}\boldsymbol{u}(\boldsymbol{x})\right]. $$
(13)

Substituting (13) into (12) and then (12) into (10) gives

$$\begin{array}{lll} \frac{\partial \sigma^{PN}_i(\boldsymbol{x})}{\partial x_b} &=&\underset{a\in \Omega_i}{\sum}\frac{\partial \sigma^{PN}_i(\boldsymbol{x})}{\partial \sigma^{vM}_a}\left( \frac{\partial \sigma^{vM}_a(\boldsymbol{x})}{\partial \boldsymbol{\sigma}_{a}} \right)^T\\ &&\times \left(\frac{\partial\eta_S(\rho_e(\boldsymbol{x}))}{\partial\rho_e}\frac{\partial\rho_e(\boldsymbol{x})}{\partial x_b} \boldsymbol{E}\boldsymbol{B}_a\boldsymbol{u}(\boldsymbol{x}) \vphantom{\left[\underset{r=1}{\overset{n_e}{\sum}}\frac{\partial\boldsymbol{K}(\boldsymbol{\rho}\left(\boldsymbol{x})\right)}{\partial\rho_r}\frac{\partial\rho_r(\boldsymbol{x})}{\partial x_b}\boldsymbol{u}(\boldsymbol{x})\right]}\right.\\ &&\,\,\,\,\quad-\,\eta_S(\rho_e(\boldsymbol{x}))\boldsymbol{E}\boldsymbol{B}_a\boldsymbol{K}^{-1}(\boldsymbol{\rho}\left(\boldsymbol{x})\right)\\ &&\,\,\,\,\quad\left.\times \left[\underset{r=1}{\overset{n_e}{\sum}}\frac{\partial\boldsymbol{K}(\boldsymbol{\rho}\left(\boldsymbol{x})\right)}{\partial\rho_r}\frac{\partial\rho_r(\boldsymbol{x})}{\partial x_b}\boldsymbol{u}(\boldsymbol{x})\right] \right). \end{array} $$
(14)

An adjoint variable \(\boldsymbol {\lambda }_i\) is now defined by

$$\boldsymbol{\lambda}_i^T= \underset{a\in \Omega_i}{\sum}\frac{\partial \sigma^{PN}_i(\boldsymbol{x})}{\partial \sigma^{vM}_a} \left( \frac{\partial \sigma^{vM}_a(\boldsymbol{x})}{\partial \boldsymbol{\sigma}_{a}} \right)^T \boldsymbol{E}\boldsymbol{B}_a\boldsymbol{K}^{-1}(\boldsymbol{\rho}\left(\boldsymbol{x})\right), $$

which means that it can be calculated from the adjoint equation:

$$\boldsymbol{K}(\boldsymbol{\rho}\left(\boldsymbol{x})\right)\boldsymbol{\lambda}_i= \underset{a\in \Omega_i}{\sum}\frac{\partial \sigma^{PN}_i(\boldsymbol{x})}{\partial \sigma^{vM}_a} \boldsymbol{B}_a^T \boldsymbol{E}^T \frac{\partial \sigma^{vM}_a(\boldsymbol{x})}{\partial \boldsymbol{\sigma}_{a}}. $$

The adjoint variable is now inserted into (14) which finally gives the gradient as

$$\begin{array}{lll} \frac{\partial \sigma^{PN}_i(\boldsymbol{x})}{\partial x_b}&=&\underset{a\in \Omega_i}{\sum}\frac{\partial \sigma^{PN}_i(\boldsymbol{x})}{\partial \sigma^{vM}_a} \left( \frac{\partial \sigma^{vM}_a(\boldsymbol{x})}{\partial \boldsymbol{\sigma}_{a}} \right)^T\\ &&\times\,\frac{\partial\eta_S(\rho_e(\boldsymbol{x}))}{\partial\rho_e}\frac{\partial\rho_e(\boldsymbol{x})}{\partial x_b}\boldsymbol{E}\boldsymbol{B}_a\boldsymbol{u}(\boldsymbol{x}) \\ &&-\,\eta_S(\rho_e(\boldsymbol{x}))\boldsymbol{\lambda}_i^{T}\\ &&\times\left[\underset{r=1}{\overset{n_e}{\sum}}\frac{\partial\boldsymbol{K}(\boldsymbol{\rho}\left(\boldsymbol{x})\right)}{\partial\rho_r}\frac{\partial\rho_r(\boldsymbol{x})}{\partial x_b}\boldsymbol{u}(\boldsymbol{x})\right], \end{array}$$

where \(\partial \sigma ^{PN}_i(\boldsymbol {x}) / \partial \sigma ^{vM}_a\) and \(\partial \sigma ^{vM}_a(\boldsymbol {x}) / \partial \boldsymbol {\sigma }_a\) were derived in Sections 7.1 and 7.2, respectively.

8 Modelling aspects

8.1 Applying loads

When stress constraints are used in the optimization problem, it is important that the loads are applied on the structure in a way that is suitable for stress calculation. A point load that can be sufficient in the traditional formulation \((\mathbb {P}_3)\) will generate a high local stress that might not be reducible, even if the entire domain becomes solid. This high stress will influence the clusters and thus also the final design. Therefore, the load has to be distributed over several nodes so that the area where the load is applied is large enough to keep the stress below the stress limit. Another approach is to exclude the elements in the vicinity of the applied load from the set of design variables: they are kept as solid structural elements that are not part of the optimization problem. Figure 3 shows a subset of a finite element mesh with a load applied at the upper right corner, the gray elements are excluded from the optimization problem.

Fig. 3
figure 3

Excluded elements highlighted in gray color

8.2 Meshing

Another consideration is the discretization, i.e. the element size. The design variable filter assures that the structural members are thicker than approximately \(2~\times ~r_0\). Thus, in order to achieve a black-and-white design when stress constraints are used, the element size must be chosen with regard to the stress limit and the filter radius. If the elements are too large, it is possible to end up in a design where the stress in a structural member with intermediate design variable values is lower than the limit, but where the structural member cannot be made thinner due to the filter. The solution might then contain structural members with intermediate design variable values, whereas a finer mesh would give thinner but solid structural members.

9 Examples

In this section we give some examples of the described method for stress constraints, applied to two dimensional structures in plane stress. The method has been implemented in the finite element program TRINITAS (Torstenfelt 2012). All designs, except for the compliance based designs, use an initial design where all \(\rho _e(\boldsymbol {x})=0.5\). The final designs that are shown in this paper have then been found by iterating well beyond convergence. Plots are appended for the final solutions shown in Tables 1 and 2. Compared to the suggested values in Svanberg (2002), the move limits in MMA have been narrowed, in order to make the solver more conservative. We note that different final solutions are obtained depending on the MMA-parameters, which is the reason why a conservative setting of the solver was preferred. As mentioned in Section 6, we do not reset MMA when a reclustering is made. The move limits in MMA are determined based on design variable values from previous iterations; in the case of reclustering, these are calculated for a somewhat different problem, but we still converge to feasible designs. The figures show the filtered variables \(\boldsymbol {\rho }\) and the penalized von Mises stresses \(\sigma _a^{vM}\). No post-processing of the pictures has been done; black means that the filtered variable is one and gray means that it is at its lowest value, \(\epsilon \). The stress contour plots should be viewed in color, the range blue-green represents stresses that are below or at the stress limit and the range yellow-red represents stresses that are above the stress limit.

Table 1 The L-beam for problem \((\mathbb {P}_1)\) using the “stress level” clustering technique and different updating frequencies
Table 2 The L-beam for problem \((\mathbb {P}_1)\) using the “distributed stress” clustering technique and different updating frequencies

9.1 The L-shaped beam

The L-shaped beam is a popular test example for stress constrained topology optimization, see Duysinx and Bendsøe (1998), Duysinx and Sigmund (1998), Le et al. (2010), París et al. (2009) among others and also Allaire and Jouve (2008), Amstutz and Novotny (2010) and Guo et al. (2011) for the L-shaped beam optimized using the level set method. The design domain of the L-shaped beam contains an internal corner with an initial geometric stress singularity, see Fig. 4. This type of design domain is convenient to use in industrial applications, where for example the L-beam can be an attachment for some piece of equipment and the corner is due to clearance to other equipment or due to the shape of the actual equipment itself. As topology optimization is a conceptual design tool, the design domain should be easy to create and simple to mesh. Thus, no radius is created at the corner of the design domain.

Fig. 4
figure 4

Geometry of the L-beam problem

The dimensions of the L-beam are seen in Fig. 4, where \(L=200\) mm and the thickness of the structure is 1 mm. The domain is meshed with 6400 equal sized four node elements and one stress evaluation point is used per element. The superconvergent point is used for stress evaluation and for this element type it is positioned in the centroid of the element. The material is a typical aircraft aluminum with material data; Young’s modulus 71,000 MPa, density \(2.8 \times 10^{-9}\) ton/mm\(^3\), Poisson’s ratio 0.33 and yield limit 350 MPa, which also is used as stress limit in the optimization. Ten clusters, i.e. ten stress constraints, are used in the numerical examples, but as shown in Fig. 5, even a much lower number of constraints gives a design that avoids high stress concentrations.

Fig. 5
figure 5

Example with only three stress constraints for the “stress level” technique and reclustering every iteration

A 1,500 N point load is applied as shown in Fig. 4 and \(3\times 2\) number of elements under the load are not part of the design space, see Fig. 3. The design variable filter is applied with a filter radius, \(r_0=1.5\) times the element size.

Solutions for the L-beam of problem formulation \((\mathbb {P}_1)\) are shown in Tables 1 and 2, where the two different clustering techniques and different reclustering frequencies are compared. As mentioned in Section 6, the case shown in (7) is approached when the stress level clustering technique is used and the clusters are updated every iteration. This is also seen in Table 1, as this combination gives the best local stress control, in an average sense, and a more even stress distribution. When the clusters are updated every 50th iteration, the local stress control is slightly worse and when the clusters are not updated at all, a large percentage of the structure have too high stress. The stress constraints are satisfied, but as the clusters were created in the first iteration, the \(\sigma _i^{PN}\) is no longer a good approximation to the local stresses. This is also the reason why the mass can be lower and why the compliance becomes higher. However, we achieve a design where the singular point is avoided more efficiently; the right vertical component is moved away from the boundary, and thus allowing for a larger radius.

We also note that a convergence plot, see Table 1, tends to have small oscillations when the clusters are updated every iteration, it makes a jump when clusters are updated every 50th iteration and is relatively smooth when no reclustering is done.

Table 2 shows the same reclustering frequencies but for the distributed stress technique, where the clusters are created from a mixture of the highest and lowest stresses. As expected, the local stress control is not as good as for the stress level technique, and the designs for different reclustering frequencies are very similar.

9.2 The MBB-beam

The MBB-beam is another popular example in topology optimization. Here symmetry is used and the right half the beam is modelled. The material, load magnitude and stress limit are the same as for the L-beam. The point load is applied at the center of the beam and the boundary conditions and dimensions are seen in Fig. 6, where \(L=100\) mm and the thickness is 1 mm. The domain is meshed with 4,800 elements, and ten clusters are used for the stress constraints. The design variable filter radius was chosen slightly larger than for the L-shaped beam, a filter radius that uses \(r_0=2\) times the element size proved to result in solutions without too many thin structural parts. Again, the elements in the vicinity of the applied load are not used as design variables in order to avoid the stress concentration.

Fig. 6
figure 6

Geometry of the MBB problem

Like the L-beam, problem \((\mathbb {P}_1)\) is solved with the two different clustering techniques and with different reclustering frequencies. The results are seen in Tables 3 and 4. The differences between the clustering techniques and the reclustering frequencies are similar to the differences obtained for the L-beam. The best design from a stress point of view is achieved with the stress level technique and reclustering every iteration.

Table 3 The MBB-beam for \((\mathbb {P}_1)\) with the “stress level” clustering technique and different updating frequencies
Table 4 The MBB-beam for \((\mathbb {P}_1)\) with the “distributed stress” clustering technique and different updating frequencies

9.3 Comparison between the three formulations

The three problem formulations \((\mathbb {P}_1)\), \((\mathbb {P}_2)\) and \((\mathbb {P}_3)\) are now compared in order to show the differences between the results and the benefit of stress constraints. In the figures in Table 5 the result for formulation \((\mathbb {P}_1)\) is reused from Table 2 and the mass that was found to be optimal is used as limit value for the mass constraint in formulations \((\mathbb {P}_2)\) and \((\mathbb {P}_3)\). There is an essential difference in the topology obtained for the L-beam for \((\mathbb {P}_3)\), in that material is placed in the corner, causing a geometrical stress singularity that would require major modifications in order to be removed. As expected, the maximum stress is lower for formulation \((\mathbb {P}_1)\) and the stress is much more evenly distributed in the structure, however this comes with the price of a lower stiffness compared to formulation \((\mathbb {P}_3)\). Therefore, formulation \((\mathbb {P}_2)\) can be used if the allowable mass is known and both stresses and stiffness are of importance. We note that it might be difficult to find a feasible design with formulation \((\mathbb {P}_2)\) when such a low allowable mass is used as in Table 5. This is the reason why the compliance becomes higher than for formulation \((\mathbb {P}_1)\). Therefore a slightly higher mass is suggested, see Fig. 7, which shows a more fair usage of formulation \((\mathbb {P}_2)\).

Table 5 Comparison of the three formulations
Fig. 7
figure 7

Formulation \((\mathbb {P}_2)\) with about 5 % higher allowable mass than in Table 5, the compliance is \(\mathrm {C}=12{,}336\)

For the MBB-beam we again see that when formulation \((\mathbb {P}_1)\) is used, a different topology is achieved compared to the compliance design for formulation \((\mathbb {P}_3)\). The height of the beam is decreasing towards the support in the right corner. This is because a bending moment arises due to the load \(F\) and it is taken as a force couple in the beam. The bending moment has its maximum value at the symmetry line where the load is applied and it decreases linearly towards zero at the support; therefore the height of the beam can be reduced towards the support in order to reduce the mass. If formulation \((\mathbb {P}_2)\) is used, we achieve a design that is closer to the design for formulation \((\mathbb {P}_3)\), but with lower stresses. With the low allowable mass used in this example, we converge to a solution where the stress constraint is not feasible. However, as for the L-beam, using a slightly higher mass will result in a feasible solution with lower compliance.

As a final remark, when solving problem \((\mathbb {P}_1)\) we have tested to start from the converged solution of the L-shaped beam obtained for problem \((\mathbb {P}_3)\), in order to see if further optimization can resolve the problem of high stresses in the internal corner. The optimization algorithm did not manage to find a feasible solution using this starting point and the final design was similar to the final design shown for \((\mathbb {P}_3)\) in Table 5.

9.4 Excluded elements

In Section 8 we discussed the possibility of excluding some selected elements from the optimization problem in order to avoid stress concentrations when point loads are applied. The excluded elements still influence the design variable filter, this helps the neighboring elements to become solid and as the loads also are distributed in another way, it is possible to drive the solution towards a desirable design. If we instead of excluding elements distribute the load over three nodes, we achieve a design that is more optimal with respect to the formulated problem, but which from a physical point of view is quite useless, as a small perturbation in load direction would cause the structure to collapse. An example is shown in the left figure in Table 6, where the figure to the right is from Table 1. Another alternative to avoid instable and weak structures is to add e.g. stiffness, buckling or eigenfrequency constraints, or to use formulation \((\mathbb {P}_2)\).

Table 6 Different designs when elements are excluded

10 Conclusions

We have developed and evaluated a method for stress constrained topology optimization. The method has been verified numerically and the results are appealing. We have shown the theoretical background and the sensitivity analysis, where we have kept the theoretical part open for 3D structures and other element types. The numerical examples show that at the cost of a more complicated and expensive optimization problem, stress constraints in topology optimization allow for designs that are closer to a final engineering design. The subsequent design work to achieve a product ready for manufacturing is thus simplified and can be done faster. Compared to formulation \((\mathbb {P}_2)\) and \((\mathbb {P}_3)\), there is in formulation \((\mathbb {P}_1)\) no need to manually test several values on the allowable mass: the minimum mass subjected to the given constraints is achieved directly. As formulation \((\mathbb {P}_1)\) has no stiffness requirements, the resulting design might have high compliance. Thus, additional stiffness, buckling or eigenfrequency constraints could be added, or alternatively, formulation \((\mathbb {P}_2)\) provides a compliant and stress constrained structure where the mass is prescribed.

From the discussion in Sections 5 and 6 and from the results for both the L-beam and the MBB-beam in Tables 14, we find that the stress level technique and reclustering is the preferable method. This combination generates simple designs that avoid stress concentrations efficiently and it only leaves a small number of points with stresses above the stress limit.

As is seen in Table 5, different topologies are achieved when stress constraints are used compared to the traditional stiffness based formulation, \((\mathbb {P}_3)\). Therefore, we claim that it is not sufficient to optimize the structure for maximum stiffness and then continue with local shape optimization to remove stress concentrations; we propose that stress constraints should be considered from the very beginning.