from __future__ import division import numpy as np import scipy class Filter(object): def __init__(self, nelx, nely, rmin): """ 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 self.H = scipy.sparse.coo_matrix((sH, (iH, jH)), shape=(nelx * nely, nelx * nely)).tocsc() self.Hs = self.H.sum(1) def filter_variables(self, x, xPhys, ft): if ft == 0: xPhys[:] = x elif ft == 1: xPhys[:] = np.asarray(self.H * x[np.newaxis].T / self.Hs)[:, 0] def filter_compliance_sensitivities(self, xPhys, dc, ft): if ft == 0: dc[:] = (np.asarray((self.H * (xPhys * dc))[np.newaxis].T / self.Hs)[:, 0] / np.maximum(0.001, xPhys)) elif ft == 1: dc[:] = np.asarray(self.H * (dc[np.newaxis].T / self.Hs))[:, 0] def filter_volume_sensitivities(self, _xPhys, dv, ft): if ft == 0: pass elif ft == 1: dv[:] = np.asarray(self.H * (dv[np.newaxis].T / self.Hs))[:, 0]