def get_weights_lin(h, Nbar, Y): """ it evaluates integral weights, which are used for upper-lower bounds calculation, with bilinear inclusion at rectangular area Parameters ---------- h - the parameter determining the size of inclusion (half-size of support) Nbar - no. of points of regular grid where the weights are evaluated Y - the size of periodic unit cell Returns ------- Wphi - integral weights at regular grid sizing Nbar """ d = np.size(Y) meas_puc = np.prod(Y) ZN2l = VecTri.get_ZNl(Nbar) Wphi = np.ones(Nbar) / meas_puc for ii in np.arange(d): Nshape = np.ones(d) Nshape[ii] = Nbar[ii] Nrep = np.copy(Nbar) Nrep[ii] = 1 Wphi *= h[ii]*np.tile(np.reshape((np.sinc(h[ii]*ZN2l[ii]/Y[ii]))**2, Nshape), Nrep) return Wphi
def get_weights_lin(h, Nbar, Y): """ it evaluates integral weights, which are used for upper-lower bounds calculation, with bilinear inclusion at rectangular area Parameters ---------- h - the parameter determining the size of inclusion (half-size of support) Nbar - no. of points of regular grid where the weights are evaluated Y - the size of periodic unit cell Returns ------- Wphi - integral weights at regular grid sizing Nbar """ d = np.size(Y) meas_puc = np.prod(Y) ZN2l = VecTri.get_ZNl(Nbar) Wphi = np.ones(Nbar) / meas_puc for ii in np.arange(d): Nshape = np.ones(d) Nshape[ii] = Nbar[ii] Nrep = np.copy(Nbar) Nrep[ii] = 1 Wphi *= h[ii] * np.tile( np.reshape((np.sinc(h[ii] * ZN2l[ii] / Y[ii]))**2, Nshape), Nrep) return Wphi
def linear_solver(Afun=None, ATfun=None, B=None, x0=None, par=None, solver=None, callback=None): """ Wraper for various linear solvers suited for FFT-based homogenization. """ if callback is not None: callback(x0) if solver.lower() in ['cg']: # conjugate gradients x, info = CG(Afun, B, x0=x0, par=par, callback=callback) elif solver.lower() in ['bicg']: # biconjugate gradients x, info = BiCG(Afun, ATfun, B, x0=x0, par=par, callback=callback) elif solver.lower() in ['iterative']: # iterative solver x, info = richardson(Afun, B, x0, par=par, callback=callback) elif solver.split('_')[0].lower() in ['scipy']: # solvers in scipy from scipy.sparse.linalg import LinearOperator, cg, bicg if solver == 'scipy_cg': Afun.define_operand(B) Afunvec = LinearOperator(Afun.shape, matvec=Afun.matvec, dtype=np.float64) xcol, info = cg(Afunvec, B.vec(), x0=x0.vec(), tol=par['tol'], maxiter=par['maxiter'], xtype=None, M=None, callback=callback) elif solver == 'scipy_bicg': Afun.define_operand(B) ATfun.define_operand(B) Afunvec = LinearOperator(Afun.shape, matvec=Afun.matvec, rmatvec=ATfun.matvec, dtype=np.float64) xcol, info = bicg(Afunvec, B.vec(), x0=x0.vec(), tol=par['tol'], maxiter=par['maxiter'], xtype=None, M=None, callback=callback) res = dict() res['info'] = info x = VecTri(val=np.reshape(xcol, B.dN())) else: msg = "This kind (%s) of linear solver is not implemented" % solver raise NotImplementedError(msg) return x, info
def __call__(self, x): self.iter += 1 if not isinstance(x, VecTri): X = VecTri(val=np.reshape(x, self.B.dN())) else: X = x res = self.B - self.A(X) self.res_norm.append(res.norm()) return
def __call__(self, x): self.iter += 1 if not isinstance(x, VecTri): X = VecTri(val=np.reshape(x, self.E2N.dN())) else: X = x if np.linalg.norm(X.mean() - self.E2N.mean()) < 1e-8: res = self.A(X) eN = X else: res = self.B-self.A(X) eN = X + self.E2N self.res_norm.append(res.norm()) GeN = self.GN*eN + self.E2N self.bound.append(self.Aex*GeN*GeN) self.in_subspace_norm.append((GeN-eN).norm()) return
def __call__(self, x): self.iter += 1 if not isinstance(x, VecTri): X = VecTri(val=np.reshape(x, self.E2N.dN())) else: X = x if np.linalg.norm(X.mean() - self.E2N.mean()) < 1e-8: res = self.A(X) eN = X else: res = self.B - self.A(X) eN = X + self.E2N self.res_norm.append(res.norm()) GeN = self.GN * eN + self.E2N self.bound.append(self.Aex * GeN * GeN) self.in_subspace_norm.append((GeN - eN).norm()) return
def add_macro2minimizer(X, E): """ The function takes the minimizers (corrector function with zero-mean property or equaling to macroscopic value) and returns a corrector function with mean that equals to macroscopic value E. """ if np.allclose(X.mean(), E): return X elif np.allclose(X.mean(), np.zeros_like(E)): return X + VecTri(name='EN', macroval=E, N=X.N, Fourier=False) else: raise ValueError("Field is neither zero-mean nor E-mean.")
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)