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_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_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 elasticity(problem): """ Homogenization of linear elasticity. Parameters ---------- problem : object """ print ' ' pb = problem print pb # Fourier projections _, hG1hN, hG1sN, hG2hN, hG2sN = proj.elasticity(pb.solve['N'], pb.Y, centered=True, NyqNul=True) del _ if pb.solve['kind'] is 'GaNi': Nbar = pb.solve['N'] elif pb.solve['kind'] is 'Ga': Nbar = 2 * pb.solve['N'] - 1 hG1hN = hG1hN.enlarge(Nbar) hG1sN = hG1sN.enlarge(Nbar) hG2hN = hG2hN.enlarge(Nbar) hG2sN = hG2sN.enlarge(Nbar) FN = DFT(name='FN', inverse=False, N=Nbar) FiN = DFT(name='FiN', inverse=True, N=Nbar) G1N = LinOper(name='G1', mat=[[FiN, hG1hN + hG1sN, FN]]) G2N = LinOper(name='G2', mat=[[FiN, hG2hN + hG2sN, FN]]) for primaldual in pb.solve['primaldual']: print '\nproblem: ' + primaldual solutions = np.zeros(pb.shape).tolist() results = np.zeros(pb.shape).tolist() # material coefficients mat = Material(pb.material) if pb.solve['kind'] is 'GaNi': A = mat.get_A_GaNi(pb.solve['N'], primaldual) elif pb.solve['kind'] is 'Ga': A = mat.get_A_Ga(Nbar=Nbar, primaldual=primaldual) if primaldual is 'primal': GN = G1N else: GN = G2N Afun = LinOper(name='FiGFA', mat=[[GN, A]]) D = pb.dim * (pb.dim + 1) / 2 for iL in np.arange(D): # iteration over unitary loads E = np.zeros(D) E[iL] = 1 print 'macroscopic load E = ' + str(E) EN = VecTri(name='EN', macroval=E, N=Nbar, Fourier=False) # initial approximation for solvers x0 = VecTri(N=Nbar, d=D, Fourier=False) B = Afun(-EN) # RHS if not hasattr(pb.solver, 'callback'): cb = CallBack(A=Afun, B=B) elif pb.solver['callback'] == 'detailed': cb = CallBack_GA(A=Afun, B=B, EN=EN, A_Ga=A, GN=GN) else: raise NotImplementedError("The solver callback (%s) is not \ implemented" % (pb.solver['callback'])) print 'solver : %s' % pb.solver['kind'] X, info = linear_solver(solver=pb.solver['kind'], Afun=Afun, B=B, x0=x0, par=pb.solver, callback=cb) solutions[iL] = add_macro2minimizer(X, E) results[iL] = {'cb': cb, 'info': info} print cb # POSTPROCESSING del Afun, B, E, EN, GN, X postprocess(pb, A, mat, solutions, results, primaldual)
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)