def shapeopt(RBF, Kinit, Vinit, iel, LSFip): # Variables nelx = variables.nelx nely = variables.nely f = variables.f si_max = variables.si_max kappa = variables.kappa rhomin = variables.rhomin edof = variables.edof # Discard/free DOFs ndof = np.max(edof) + 1 dofs = np.arange(ndof) disc = np.setdiff1d(edof[iel == 0, :], edof[iel != 0, :]) free = np.setdiff1d(dofs, np.append(variables.fix, disc)) dofs[np.append(variables.fix, disc)] = -1 # Optimizer initialization (MMA) mma = optimizers.MMA(variables.nele, dmax=si_max, dmin=-si_max, movelimit=0.2, asy=(0.5, 1.2, 0.65), scaling=True) x = RBF[:, :, 2].T.reshape(-1).copy() iter = 1 while iter < 10.5: # Stiffness matrix phi = LSFip.dot(x[:]) rho = rhomin + (1 - rhomin) * (1 / (1 + np.exp(-kappa * phi))) K = FCM.K(Kinit, iel, rho) # Reverse Cuthill-McKee ordering ind = sp.csgraph.reverse_cuthill_mckee(K, symmetric_mode=True) free = dofs[ind][dofs[ind] != -1] # Solve (reduced) system u = np.zeros((np.size(K, 0), )) u[free] = solver(K[free, :][:, free], f[free]) # Compliance objective and its sensitivity [C, dC] = obj(Kinit, iel, LSFip, u, phi, rho, f, free) # Volume fraction constraint and its sensitivity [g, dg] = constr(Vinit, iel, LSFip, phi, rho) # Shape optimization dx = mma.solve(x, C, dC, g, dg, iter) x = x + dx # Update log print(['%.3f' % i for i in [iter, C, g]]) iter += 1 RBF[:, :, 2] = x.reshape(nely, nelx).T return RBF