Exemple #1
0
 def forces(self):
     """Return the force vector for the problem."""
     f = numpy.zeros((2 * (self.nelx + 1) * (self.nely + 1), 1))
     id1 = 2 * xy_to_id(7 * self.nelx // 20, 0, self.nelx, self.nely) + 1
     id2 = 2 * xy_to_id(13 * self.nelx // 20, 0, self.nelx, self.nely) + 1
     f[[id1, id2], 0] = -1
     return f
Exemple #2
0
 def get_fixed_nodes(self):
     # Return a list of fixed nodes for the problem
     bottom_left = 2 * xy_to_id(0, self.nely, self.nelx, self.nely)
     bottom_right = 2 * xy_to_id(self.nelx, self.nely, self.nelx, self.nely)
     fixed = np.array(
         [bottom_left, bottom_left + 1, bottom_right, bottom_right + 1])
     return fixed
Exemple #3
0
 def fixed_nodes(self):
     """Return a list of fixed nodes for the problem."""
     bottom_left = 2 * xy_to_id(0, self.nely, self.nelx, self.nely)
     bottom_right = 2 * xy_to_id(self.nelx, self.nely, self.nelx, self.nely)
     fixed = numpy.array(
         [bottom_left, bottom_left + 1, bottom_right, bottom_right + 1])
     return fixed
Exemple #4
0
 def get_fixed_nodes(self):
     # Return a list of fixed nodes for the problem
     bottom_left = 2 * xy_to_id(0, self.nely, self.nelx, self.nely)
     bottom_right = 2 * xy_to_id(
         self.nelx, self.nely, self.nelx, self.nely)
     fixed = np.array([bottom_left, bottom_left + 1,
         bottom_right, bottom_right + 1])
     return fixed
Exemple #5
0
    def on_press(self, event):
        """Create a hole at the point pressed."""
        # Clamp the point to the domain
        selected_x = int(max(0, min(self.nelx, numpy.round(event.xdata))))
        selected_y = int(max(0, min(self.nely, numpy.round(event.ydata))))
        print("Selected: x = {:d}, y = {:d}".format(selected_x, selected_y))

        selected_point = numpy.array([selected_x, selected_y])

        def dist_from_selected_point(x, y):
            """Compute the distance from the selected_point."""
            return numpy.linalg.norm(selected_point - numpy.array([x, y]))

        # Create a bounding box of the selected point and the selection radius
        min_x = max(0, selected_x - self.radius + 1)
        max_x = min(self.nelx, selected_x + self.radius)
        min_y = max(0, selected_y - self.radius + 1)
        max_y = min(self.nely, selected_y + self.radius)
        for x in range(min_x, max_x):
            for y in range(min_y, max_y):
                if dist_from_selected_point(x, y) <= self.radius:
                    solver.xPhys[xy_to_id(
                        x, y, self.nelx - 1,
                        self.nely - 1)] = (0.0 if event.button == 1 else 1.0)

        self.problem.compute_objective2(solver.xPhys, self.problem.dstress)
Exemple #6
0
 def get_passive_elements(self):
     X, Y = np.mgrid[self.passive_min_x:self.passive_max_x + 1,
                     self.passive_min_y:self.passive_max_y]
     pairs = np.vstack([X.ravel(), Y.ravel()]).T
     passive_to_ids = np.vectorize(lambda pair: xy_to_id(
         *pair, nelx=self.nelx - 1, nely=self.nely - 1),
                                   signature="(m)->()")
     return passive_to_ids(pairs)
Exemple #7
0
 def get_fixed_nodes(self):
     """ Return a list of fixed nodes for the problem. """
     x = np.arange(self.passive_min_x)
     topx_to_id = np.vectorize(
         lambda x: xy_to_id(x, 0, self.nelx, self.nely))
     ids = topx_to_id(x)
     fixed = np.union1d(2 * ids, 2 * ids + 1)
     return fixed
Exemple #8
0
 def get_forces(self):
     # Return the force vector for the problem
     topx_to_id = np.vectorize(
         lambda x: xy_to_id(x, 0, self.nelx, self.nely))
     topx = 2 * topx_to_id(np.arange((self.nelx + 1) // 2)) + 1
     f = np.zeros((2 * (self.nelx + 1) * (self.nely + 1), 1))
     f[topx, 0] = -100
     return f
Exemple #9
0
 def forces(self):
     """Return the force vector for the problem."""
     topx_to_id = numpy.vectorize(
         lambda x: xy_to_id(x, 0, self.nelx, self.nely))
     topx = 2 * topx_to_id(numpy.arange(self.nelx + 1)) + 1
     f = numpy.zeros((2 * (self.nelx + 1) * (self.nely + 1), 1))
     f[topx, 0] = -1
     return f
Exemple #10
0
 def get_forces(self):
     # Return the force vector for the problem
     topx_to_id = np.vectorize(
         lambda x: xy_to_id(x, 0, self.nelx, self.nely))
     topx = 2 * topx_to_id(np.arange((self.nelx + 1) // 2)) + 1
     f = np.zeros((2 * (self.nelx + 1) * (self.nely + 1), 1))
     f[topx, 0] = -100
     return f
Exemple #11
0
 def fixed_nodes(self):
     """Return a list of fixed nodes for the problem."""
     x = numpy.arange(self.nelx + 1)
     botx_to_id = numpy.vectorize(
         lambda x: xy_to_id(x, self.nely, self.nelx, self.nely))
     ids = 2 * botx_to_id(x)
     fixed = numpy.union1d(ids, ids + 1)
     return fixed
Exemple #12
0
 def nonuniform_forces(self):
     """Return the force vector for the problem."""
     topx_to_id = numpy.vectorize(
         lambda x: xy_to_id(x, 0, self.nelx, self.nely))
     topx = 2 * topx_to_id(numpy.arange(self.nelx + 1)) + 1
     f = numpy.zeros((2 * (self.nelx + 1) * (self.nely + 1), 1))
     f[topx, 0] = (0.5 * numpy.cos(
         numpy.linspace(0, 2 * numpy.pi, topx.shape[0])) - 0.5)
     return f
 def forces(self):
     """Return the force vector for the problem."""
     topx_to_id = numpy.vectorize(
         lambda x: xy_to_id(x, 0, self.nelx, self.nely))
     topx = 2 * topx_to_id(numpy.arange(self.nelx + 1)) + 1
     nForces = topx.shape[0]
     cols = numpy.arange(nForces)
     f = numpy.zeros((2 * (self.nelx + 1) * (self.nely + 1), nForces))
     f[topx, cols] = -1
     return f
Exemple #14
0
 def forces(self):
     """Return the force vector for the problem."""
     ndof = 2 * (self.nelx + 1) * (self.nely + 1)
     x = numpy.arange(0, self.nelx + 1, 10)
     topx_to_id = numpy.vectorize(
         lambda x: xy_to_id(x, 0, self.nelx, self.nely))
     ids = 2 * topx_to_id(x) + 1
     f = numpy.zeros((ndof, 1))
     f[ids] = -1
     return f
Exemple #15
0
 def get_forces(self):
     """ Return the force vector for the problem. """
     ndof = 2 * (self.nelx + 1) * (self.nely + 1)
     f = np.zeros((ndof, 1))
     fx = self.nelx
     # fy = (self.nely - self.passive_max_y) // 2 + self.passive_max_y
     for i in range(1, 2):
         fy = self.passive_max_y - 1 + 2 * i
         id = xy_to_id(fx, fy, self.nelx, self.nely)
         f[2 * id + 1, 0] = -1
     return f
Exemple #16
0
def onrelease(event):
    if event.button == 1:
        global selected_x, selected_y
        dx = event.xdata - selected_x
        dy = event.ydata - selected_y
        id = xy_to_id(selected_x, selected_y, nelx, nely)
        u[2 * id] += dx
        u[2 * id + 1] += dy
        stress = vms.calculate_stress(xPhys, u, nu)
        im.set_array(stress.reshape((nelx, nely)).T)
        set_labels(stress.reshape((nelx, nely)).T)
        print("Released: dx = {:g}, dy = {:g}".format(dx, dy))
        selected_x = selected_y = None
Exemple #17
0
def onpress(event):
    global selected_x, selected_y
    selected_x = int(max(0, min(nelx, numpy.round(event.xdata))))
    selected_y = int(max(0, min(nely, numpy.round(event.ydata))))
    if event.button == 1:
        print("Selected: x = {:d}, y = {:d}".format(selected_x, selected_y))
    else:
        id = xy_to_id(selected_x, selected_y, nelx, nely)
        u[2 * id] = 0
        u[2 * id + 1] = 0
        stress = vms.calculate_stress(xPhys, u, nu)
        im.set_array(stress.reshape((nelx, nely)).T)
        set_labels(stress.reshape((nelx, nely)).T)
        selected_x = selected_y = None
Exemple #18
0
def set_displacements(u,
                      func,
                      nelx,
                      nely,
                      min_corner=(-1, -1),
                      max_corner=(1, 1)):
    for i in range(nelx + 1):
        for j in range(nely + 1):
            id = xy_to_id(i, j, nelx, nely)
            x = min_corner[0] + (i / nelx) * (max_corner[0] - min_corner[0])
            y = min_corner[1] + (j / nely) * (max_corner[1] - min_corner[1])
            fx, fy = func(x, y)
            u[2 * id] = fx
            u[2 * id + 1] = fy
Exemple #19
0
def main(nelx, nely, volfrac, penalty, rmin, ft):
    print("Minimum compliance problem with OC")
    print("ndes: %d x %d" % (nelx, nely))
    print("volfrac: %s, rmin: %s, penalty: %s" % (volfrac, rmin, penalty))
    print("Filter method: " + ["Sensitivity based", "Density based"][ft])
    # Max and min stiffness
    Emin = 1e-9
    Emax = 1.0
    # dofs:
    ndof = 2 * (nelx + 1) * (nely + 1)
    # Allocate design variables (as array),  initialize and allocate sens.
    x = volfrac * np.ones(nely * nelx)
    xold = x.copy()
    xPhys = x.copy()
    g = 0  # must be initialized to use the NGuyen/Paulino OC approach
    dc = np.zeros((nely, nelx))
    # FE: Build the index vectors for the for coo matrix format.
    KE = lk()
    edofMat = np.zeros((nelx * nely, 8), dtype=int)
    for elx in range(nelx):
        for ely in range(nely):
            el = ely + elx * nely
            n1 = (nely + 1) * elx + ely
            n2 = (nely + 1) * (elx + 1) + ely
            edofMat[el, :] = np.array([
                2 * n1 + 2, 2 * n1 + 3, 2 * n2 + 2, 2 * n2 + 3, 2 * n2,
                2 * n2 + 1, 2 * n1, 2 * n1 + 1
            ])
    # Construct the index pointers for the coo format
    iK = np.kron(edofMat, np.ones((8, 1))).flatten()
    jK = np.kron(edofMat, np.ones((1, 8))).flatten()
    # Filter: Build (and assemble) the index + data vectors for the coo matrix
    # format
    nfilter = int(nelx * nely * ((2 * (np.ceil(rmin) - 1) + 1)**2))
    iH = np.zeros(nfilter)
    jH = np.zeros(nfilter)
    sH = np.zeros(nfilter)
    cc = 0
    for i in range(nelx):
        for j in range(nely):
            row = i * nely + j
            kk1 = int(np.maximum(i - (np.ceil(rmin) - 1), 0))
            kk2 = int(np.minimum(i + np.ceil(rmin), nelx))
            ll1 = int(np.maximum(j - (np.ceil(rmin) - 1), 0))
            ll2 = int(np.minimum(j + np.ceil(rmin), nely))
            for k in range(kk1, kk2):
                for l in range(ll1, ll2):
                    col = k * nely + l
                    fac = rmin - np.sqrt(
                        ((i - k) * (i - k) + (j - l) * (j - l)))
                    iH[cc] = row
                    jH[cc] = col
                    sH[cc] = np.maximum(0.0, fac)
                    cc = cc + 1
    # Finalize assembly and convert to csc format
    H = coo_matrix((sH, (iH, jH)), shape=(nelx * nely, nelx * nely)).tocsc()
    Hs = H.sum(1)
    # BC's and support
    dofs = np.arange(2 * (nelx + 1) * (nely + 1))
    bottom_left = 2 * xy_to_id(0, nely, nelx, nely)
    bottom_right = 2 * xy_to_id(nelx, nely, nelx, nely)
    fixed = np.array(
        [bottom_left, bottom_left + 1, bottom_right, bottom_right + 1])
    free = np.setdiff1d(dofs, fixed)
    # Solution and RHS vectors
    f = np.zeros((ndof, 2))
    u = np.zeros((ndof, 2))
    # Set load
    f = np.zeros((2 * (nelx + 1) * (nely + 1), 2))
    id1 = 2 * xy_to_id(7 * nelx // 20, 0, nelx, nely) + 1
    id2 = 2 * xy_to_id(13 * nelx // 20, 0, nelx, nely) + 1
    f[id1, 0] = -1
    f[id2, 1] = -1
    # f[1, 0] = -1
    # f[2 * (nelx - 1) * (nely + 1), 1] =  -1
    # Initialize plot and plot the initial design
    plt.ion()  # Ensure that redrawing is possible
    fig, ax = plt.subplots()
    im = ax.imshow(-xPhys.reshape((nelx, nely)).T,
                   cmap='gray',
                   interpolation='none',
                   norm=colors.Normalize(vmin=-1, vmax=0))
    plt.xlabel(
        "ndes: {:d} x {:d}\nvolfrac: {:g}, rmin: {:g}, penalty: {:g}".format(
            nelx, nely, volfrac, rmin, penalty))
    plot_force_arrows(nelx, nely, f, ax)
    fig.tight_layout()
    fig.show()
    # Set loop counter and gradient vectors
    dv = np.ones(nely * nelx)
    ce = np.ones(nely * nelx)
    for loop in range(2000):  # while change > 0.01 and loop < 100:
        # Setup and solve FE problem
        sK = ((KE.flatten()[np.newaxis]).T *
              (Emin + (xPhys)**penalty * (Emax - Emin))).flatten(order='F')
        K = coo_matrix((sK, (iK, jK)), shape=(ndof, ndof)).tocsc()
        # Remove constrained dofs from matrix
        K = deleterowcol(K, fixed, fixed).tocoo()
        # Solve system
        # u[free, :] = spsolve(K.tocsc(), f[free, :])
        K = cvxopt.spmatrix(K.data, K.row, K.col)
        B = cvxopt.matrix(f[free, :])
        cvxopt.cholmod.linsolve(K, B)
        u[free, :] = np.array(B)[:, :]
        # Objective and sensitivity
        obj = 0
        dc = np.zeros(nely * nelx)
        # import pdb; pdb.set_trace()
        for i in range(f.shape[1]):
            ui = u[:, i][edofMat]
            ce[:] = (ui.dot(KE) * ui).sum(1)
            obj += ((Emin + xPhys**penalty * (Emax - Emin)) * ce).sum()
            dc[:] += (-penalty * xPhys**(penalty - 1) * (Emax - Emin)) * ce
        dv[:] = np.ones(nely * nelx)
        # Sensitivity filtering:
        if ft == 0:
            dc[:] = (np.asarray((H * (x * dc))[np.newaxis].T / Hs)[:, 0] /
                     np.maximum(0.001, x))
        elif ft == 1:
            dc[:] = np.asarray(H * (dc[np.newaxis].T / Hs))[:, 0]
            dv[:] = np.asarray(H * (dv[np.newaxis].T / Hs))[:, 0]
        # Optimality criteria
        xold[:] = x
        (x[:], g) = oc(nelx, nely, x, volfrac, dc, dv, g)
        # Filter design variables
        if ft == 0:
            xPhys[:] = x
        elif ft == 1:
            xPhys[:] = np.asarray(H * x[np.newaxis].T / Hs)[:, 0]
        # Compute the change by the inf. norm
        change = (np.linalg.norm(
            x.reshape(nelx * nely, 1) - xold.reshape(nelx * nely, 1), np.inf))
        # Plot to screen
        im.set_array(-xPhys.reshape((nelx, nely)).T)
        fig.canvas.draw()
        fig.canvas.flush_events()
        plt.pause(0.005)
        # Write iteration history to screen
        print("it.: %3d, obj.: %9.3f, Vol.: %.2f, ch.: %.3f" %
              (loop, obj, (g + volfrac * nelx * nely) / (nelx * nely), change))
        if change < 0.01:
            break
    # Make sure the plot stays and that the shell remains
    plt.show()
    input("Press any key...")