示例#1
0
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
示例#2
0
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
示例#3
0
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
示例#4
0
 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
示例#5
0
    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
示例#6
0
    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
示例#7
0
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.")
示例#8
0
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)