def get_shape_functions(self, N2): N2 = np.array(N2, dtype=np.int32) inclusions = self.conf['inclusions'] params = self.conf['params'] positions = self.conf['positions'] chars = [] for ii, incl in enumerate(inclusions): position = positions[ii] if isinstance(position, np.ndarray): SS = get_shift_inclusion(N2, position, self.Y) if incl in inclusion_keys['cube']: h = params[ii] Wraw = get_weights_con(h, N2, self.Y) chars.append(np.real(DFT.ifftnc(SS*Wraw, N2))*np.prod(N2)) elif incl in inclusion_keys['ball']: r = params[ii]/2 if r == 0: Wraw = np.zeros(N2) else: Wraw = get_weights_circ(r, N2, self.Y) chars.append(np.real(DFT.ifftnc(SS*Wraw, N2))*np.prod(N2)) elif incl == 'all': chars.append(np.ones(N2)) elif incl == 'otherwise': chars.append(np.ones(N2)) for ii in np.arange(len(inclusions)-1): chars[-1] -= chars[ii] else: msg = 'The inclusion (%s) is not supported!' % (incl) raise NotImplementedError(msg) return chars
def get_shape_functions(self, N2): """ Returns stiffness matrix for exact integration scheme for individual inclusions (square, circle, etc.). """ N2 = np.array(N2, dtype=np.int32) inclusions = self.conf['inclusions'] params = self.conf['params'] positions = self.conf['positions'] chars = [] for ii, incl in enumerate(inclusions): position = positions[ii] if isinstance(position, np.ndarray): SS = get_shift_inclusion(N2, position, self.Y) if incl in inclusion_keys['cube']: Wraw = get_weights_con(params[ii], N2, self.Y) chars.append(np.real(DFT.ifftnc(SS * Wraw, N2)) * np.prod(N2)) elif incl in inclusion_keys['ball']: r = params[ii] / 2 if r == 0: Wraw = np.zeros(N2) else: Wraw = get_weights_circ(r, N2, self.Y) chars.append(np.real(DFT.ifftnc(SS * Wraw, N2)) * np.prod(N2)) elif incl in inclusion_keys['pyramid']: Wraw = get_weights_lin(params[ii] / 2., N2, self.Y) chars.append(np.real(DFT.ifftnc(SS * Wraw, N2)) * np.prod(N2)) elif incl == 'all': chars.append(np.ones(N2)) elif incl == 'otherwise': chars.append(np.ones(N2)) for ii in np.arange(len(inclusions) - 1): chars[-1] -= chars[ii] else: msg = 'The inclusion (%s) is not supported!' % (incl) raise NotImplementedError(msg) return chars
def get_A_Ga(self, Nbar, primaldual='primal', order=None, P=None): """ Returns stiffness matrix for scheme with exact integration.""" if order is None and 'order' in self.conf: order = self.conf['order'] if order is None: shape_funs = self.get_shape_functions(Nbar) val = np.zeros(self.conf['vals'][0].shape + shape_funs[0].shape) for ii in range(len(self.conf['inclusions'])): if primaldual is 'primal': Aincl = self.conf['vals'][ii] elif primaldual is 'dual': Aincl = np.linalg.inv(self.conf['vals'][ii]) val += np.einsum('ij...,k...->ijk...', Aincl, shape_funs[ii]) return Matrix(name='A_Ga', val=val, Fourier=False) else: if P is None and 'P' in self.conf: P = self.conf['P'] coord = Grid.get_coordinates(P, self.Y) vals = self.evaluate(coord) dim = vals.d if primaldual is 'dual': vals = vals.inv() h = self.Y/P if order in [0, 'constant']: Wraw = get_weights_con(h, Nbar, self.Y) elif order in [1, 'bilinear']: Wraw = get_weights_lin(h, Nbar, self.Y) Aapp = np.zeros(np.hstack([dim, dim, Nbar])) for m in np.arange(dim): for n in np.arange(dim): hAM0 = DFT.fftnc(vals[m, n], P) if np.allclose(P, Nbar): hAM = hAM0 elif np.all(np.greater_equal(P, Nbar)): hAM = decrease(hAM0, Nbar) elif np.all(np.less(P, Nbar)): factor = np.ceil(np.array(Nbar, dtype=np.float64) / P) hAM0per = np.tile(hAM0, 2*factor-1) hAM = decrease(hAM0per, Nbar) else: raise ValueError() pNbar = np.prod(Nbar) """ if DFT is normalized in accordance with articles there should be np.prod(M) instead of np.prod(Nbar)""" Aapp[m, n] = np.real(pNbar*DFT.ifftnc(Wraw*hAM, Nbar)) name = 'A_Ga_o%d_P%d' % (order, P.max()) return Matrix(name=name, val=Aapp, Fourier=False)
def get_A_Ga(self, Nbar, primaldual='primal', order=-1, P=None): """ Returns stiffness matrix for scheme with exact integration. """ if order == -1: if 'order' in self.conf: order = self.conf['order'] else: raise ValueError('The material order is undefined!') elif order not in [None, 'exact', 0, 1]: raise ValueError('Wrong material order (%s)!' % str(order)) if order in [None, 'exact']: shape_funs = self.get_shape_functions(Nbar) val = np.zeros(self.conf['vals'][0].shape + shape_funs[0].shape) for ii in range(len(self.conf['inclusions'])): if primaldual is 'primal': Aincl = self.conf['vals'][ii] elif primaldual is 'dual': Aincl = np.linalg.inv(self.conf['vals'][ii]) val += np.einsum('ij...,k...->ijk...', Aincl, shape_funs[ii]) name = 'A_Ga' else: if P is None and 'P' in self.conf: P = self.conf['P'] coord = Grid.get_coordinates(P, self.Y) vals = self.evaluate(coord) dim = vals.d if primaldual is 'dual': vals = vals.inv() h = self.Y / P if order in [0, 'constant']: Wraw = get_weights_con(h, Nbar, self.Y) elif order in [1, 'bilinear']: Wraw = get_weights_lin(h, Nbar, self.Y) val = np.zeros(np.hstack([dim, dim, Nbar])) for m in np.arange(dim): for n in np.arange(dim): hAM0 = DFT.fftnc(vals[m, n], P) if np.allclose(P, Nbar): hAM = hAM0 elif np.all(np.greater_equal(P, Nbar)): hAM = decrease(hAM0, Nbar) elif np.all(np.less(P, Nbar)): factor = np.ceil(np.array(Nbar, dtype=np.float64) / P) hAM0per = np.tile(hAM0, 2 * factor - 1) hAM = decrease(hAM0per, Nbar) else: raise ValueError() pNbar = np.prod(Nbar) """ if DFT is normalized in accordance with articles there should be np.prod(M) instead of np.prod(Nbar)""" val[m, n] = np.real(pNbar * DFT.ifftnc(Wraw * hAM, Nbar)) name = 'A_Ga_o%d_P%d' % (order, P.max()) return Matrix(name=name, val=val, Fourier=False)