Compliance with prescribed displacements

Example of the design for stiffness of a structure subjected to prescribed displacements

This example peforms the topology optimization considering:

  1. Maximum stiffness between prescribed displacements and support

  2. Constrained by maximum volume

The optimization is similar to Compliance minimization, which applies a load instead of a prescribed displacement. When optimizing for a maximum stiffness design, the compliance \(c=\mathbf{u}\cdot\mathbf{f}\) must be minimized when applying a load, while it must be maximized when a displacement is prescribed.

To solve a system of equations with applied displacement, the pymoto.SystemOfEquations module is used.

References:

Koppen, S., Langelaar, M., & van Keulen, F. (2022). A simple and versatile topology optimization formulation for flexure synthesis. Mechanism and Machine Theory, 172, 104743. DOI: http://dx.doi.org/10.1016/j.mechmachtheory.2022.104743

25 import numpy as np
26 import pymoto as pym
27
28 # Problem settings
29 nx, ny = 40, 40  # Domain size
30 xmin, filter_radius, volfrac = 1e-9, 2, 0.5  # Density settings
31 nu, E = 0.3, 1.0  # Material properties
32
33 if __name__ == "__main__":
34     # Set up the domain
35     domain = pym.VoxelDomain(nx, ny)
36
37     # Node and dof groups
38     nodes_left = domain.nodes[0, :].flatten()
39     nodes_right = domain.nodes[-1, :].flatten()
40     dofs_left_x = domain.get_dofnumber(nodes_left, 0, 2).flatten()
41     dofs_left_y = domain.get_dofnumber(nodes_left, 1, 2).flatten()
42     dofs_right = domain.get_dofnumber(nodes_right, np.arange(2), 2).flatten()
43
44     all_dofs = np.arange(0, 2 * domain.nnodes)
45     prescribed_dofs = np.unique(np.concatenate([dofs_left_x, dofs_right, dofs_left_y]))
46     free_dofs = np.setdiff1d(all_dofs, prescribed_dofs)
47
48     # Setup solution vectors and rhs
49     ff = np.zeros_like(free_dofs, dtype=float)
50     u = np.zeros_like(all_dofs, dtype=float)
51
52     u[dofs_left_y] = 1.0
53     up = u[prescribed_dofs]
54
55     # Initial design
56     s_x = pym.Signal('x', state=volfrac * np.ones(domain.nel))
57
58     # Setup optimization problem
59     with pym.Network() as fn:
60         # Density filtering
61         s_xfilt = pym.DensityFilter(domain, radius=filter_radius)(s_x)
62         s_xfilt.tag = 'xfiltered'
63
64         # SIMP penalization
65         s_xsimp = pym.MathExpression(f"{xmin} + {1 - xmin}*inp0^3")(s_xfilt)
66
67         # Matrix assembly
68         s_K = pym.AssembleStiffness(domain, e_modulus=E, poisson_ratio=nu)(s_xsimp)
69
70         # Solve system of equations
71         s_u, s_f = pym.SystemOfEquations(prescribed=prescribed_dofs)(s_K, ff, up)
72
73         # Calculate compliance value
74         s_c = pym.EinSum('i,i->')(s_u, s_f)
75
76         # Objective function (note the sign!)
77         s_gobj =pym.Scaling(scaling=-1)(s_c)
78         s_gobj.tag = "Objective"
79
80         # Volume
81         s_vol = pym.EinSum('i->')(s_xfilt)
82         s_vol.tag = "volume"
83
84         # Volume constraint
85         s_gvol = pym.Scaling(scaling=10.0, maxval=volfrac * domain.nel)(s_vol)
86         s_gvol.tag = "Volume constraint"
87
88         # Plotting
89         pym.PlotDomain(domain, saveto="out/design")(s_xfilt)
90         optimization_responses = [s_gobj, s_gvol]
91         pym.PlotIter()(*optimization_responses)
92
93     # Run optimization
94     pym.minimize_mma(s_x, optimization_responses, verbosity=2)

Gallery generated by Sphinx-Gallery