Пример #1
0
    def test_solvers(self):
        print('\nChecking solvers...')
        dim = 2
        n = 5
        N = n * np.ones(dim, dtype=np.int)

        _, hG1Nt, _ = scalar_tensor(N, Y=np.ones(dim))

        FN = DFT(name='FN', inverse=False, N=N)
        FiN = DFT(name='FiN', inverse=True, N=N)

        G1N = Operator(name='G1', mat=[[FiN, hG1Nt, FN]])

        A = Tensor(name='A',
                   val=np.einsum('ij,...->ij...', np.eye(dim),
                                 1. + 10. * np.random.random(N)),
                   order=2,
                   N=N,
                   multype=21)

        E = np.zeros((dim, ) + dim * (n, ))
        E[0] = 1.  # set macroscopic loading
        E = Tensor(name='E', val=E, order=1, N=N)

        GAfun = Operator(name='GA', mat=[[G1N, A]])
        GAfun.define_operand(E)

        B = GAfun(-E)
        x0 = E.copy(name='x0')
        x0.val[:] = 0

        par = {
            'tol': 1e-10,
            'maxiter': int(1e3),
            'alpha': 0.5 * (1. + 10.),
            'eigrange': [1., 10.]
        }

        # reference solution
        X, _ = linear_solver(Afun=GAfun, B=B, x0=x0, par=par, solver='CG')

        prt.disable()
        for solver in ['CG', 'scipy_cg', 'richardson', 'chebyshev']:
            x, _ = linear_solver(Afun=GAfun,
                                 B=B,
                                 x0=x0,
                                 par=par,
                                 solver=solver)
            self.assertAlmostEqual(0,
                                   norm(X.val - x.val),
                                   delta=1e-8,
                                   msg=solver)
        prt.enable()

        print('...ok')
Пример #2
0
    def test_solvers(self):
        print('\nChecking solvers...')
        dim=2
        n=5
        N = n*np.ones(dim, dtype=np.int)

        _, hG1Nt, _ = scalar_tensor(N, Y=np.ones(dim))

        FN=DFT(name='FN', inverse=False, N=N)
        FiN=DFT(name='FiN', inverse=True, N=N)

        G1N=Operator(name='G1', mat=[[FiN, hG1Nt, FN]])

        A=Tensor(name='A', val=np.einsum('ij,...->ij...', np.eye(dim), 1.+10.*np.random.random(N)),
                 order=2, N=N, multype=21)

        E=np.zeros((dim,)+dim*(n,)); E[0] = 1. # set macroscopic loading
        E=Tensor(name='E', val=E, order=1, N=N)

        GAfun=Operator(name='GA', mat=[[G1N, A]])
        GAfun.define_operand(E)

        B=GAfun(-E)
        x0=E.copy(name='x0')
        x0.val[:]=0

        par={'tol': 1e-10,
             'maxiter': int(1e3),
             'alpha': 0.5*(1.+10.),
             'eigrange':[1., 10.]}

        # reference solution
        X,_=linear_solver(Afun=GAfun, B=B, x0=x0, par=par, solver='CG')

        prt.disable()
        for solver in ['CG', 'scipy_cg', 'richardson', 'chebyshev']:
            x,_=linear_solver(Afun=GAfun, B=B, x0=x0, par=par, solver=solver)
            self.assertAlmostEqual(0, norm(X.val-x.val), delta=1e-8, msg=solver)
        prt.enable()

        print('...ok')
Пример #3
0
def homog_Ga_full_potential(Aga, pars):

    Nbar = Aga.N  # double grid number
    N = np.array((np.array(Nbar) + 1) / 2, dtype=np.int)

    dim = Nbar.__len__()

    F2 = DFT(name='FN', inverse=False,
             N=Nbar)  # discrete Fourier transform (DFT)
    iF2 = DFT(name='FiN', inverse=True, N=Nbar)  # inverse DFT

    P = get_preconditioner(N, pars)

    E = np.zeros(dim)
    E[0] = 1  # macroscopic load
    EN = Tensor(name='EN', N=Nbar, shape=(dim, ),
                Fourier=False)  # constant trig. pol.
    EN.set_mean(E)

    def DFAFGfun(X):
        assert (X.Fourier)
        FAX = F2(Aga * iF2(grad(X).enlarge(Nbar)))
        FAX = FAX.project(N)
        return -div(FAX)

    B = div(F2(Aga(EN)).decrease(N))
    x0 = Tensor(N=N, shape=(),
                Fourier=True)  # initial approximation to solvers

    PDFAFGPfun = lambda Fx: P * DFAFGfun(P * Fx)
    PB = P * B

    tic = Timer(name='CG (potential)')
    iPU, info = linear_solver(solver='CG',
                              Afun=PDFAFGPfun,
                              B=PB,
                              x0=x0,
                              par=pars.solver,
                              callback=None)
    tic.measure()

    print(('iterations of CG={}'.format(info['kit'])))
    print(('norm of residuum={}'.format(info['norm_res'])))
    R = PB - PDFAFGPfun(iPU)
    print(('norm of residuum={} (from definition)'.format(R.norm())))

    Fu = P * iPU
    X = iF2(grad(Fu).project(Nbar))

    AH = Aga(X + EN) * (X + EN)

    return Struct(AH=AH, e=X, Fu=Fu, info=info, time=tic.vals[0][0])
Пример #4
0
def homog_GaNi_full_potential(Agani, Aga, pars):

    N = Agani.N  # double grid number
    dim = N.__len__()

    F = DFT(name='FN', inverse=False, N=N)  # discrete Fourier transform (DFT)
    iF = DFT(name='FiN', inverse=True, N=N)  # inverse DFT

    P = get_preconditioner(N, pars)

    E = np.zeros(dim)
    E[0] = 1  # macroscopic load
    EN = Tensor(name='EN', N=N, shape=(dim, ),
                Fourier=False)  # constant trig. pol.
    EN.set_mean(E)

    def DFAFGfun(X):
        assert (X.Fourier)
        FAX = F(Agani * iF(grad(X)))
        return -div(FAX)

    B = div(F(Agani(EN)))
    x0 = Tensor(N=N, shape=(),
                Fourier=True)  # initial approximation to solvers

    PDFAFGPfun = lambda Fx: P * DFAFGfun(P * Fx)
    PB = P * B
    tic = Timer(name='CG (potential)')
    iPU, info = linear_solver(solver='CG',
                              Afun=PDFAFGPfun,
                              B=PB,
                              x0=x0,
                              par=pars.solver,
                              callback=None)
    tic.measure()
    print(('iterations of CG={}'.format(info['kit'])))
    print(('norm of residuum={}'.format(info['norm_res'])))

    Fu = P * iPU
    if Aga is None:  # GaNi homogenised properties
        print('!!!!! homogenised properties are GaNi only !!!!!')
        XEN = iF(grad(Fu)) + EN
        AH = Agani(XEN) * XEN
    else:
        Nbar = 2 * np.array(N) - 1
        iF2 = DFT(name='FiN', inverse=True, N=Nbar)  # inverse DFT
        XEN = iF2(grad(Fu).project(Nbar)) + EN.project(Nbar)
        AH = Aga(XEN) * XEN

    return Struct(AH=AH, Fu=Fu, info=info, time=tic.vals[0][0], pars=pars)
Пример #5
0
def homog_Ga_full(Aga, pars):
    Nbar = Aga.N
    N = np.array((np.array(Nbar) + 1) / 2, dtype=np.int)
    dim = Nbar.__len__()
    Y = np.ones(dim)
    _, Ghat, _ = proj.scalar(N, Y)
    Ghat2 = Ghat.enlarge(Nbar)
    F2 = DFT(name='FN', inverse=False,
             N=Nbar)  # discrete Fourier transform (DFT)
    iF2 = DFT(name='FiN', inverse=True, N=Nbar)  # inverse DFT

    G1N = Operator(name='G1', mat=[[iF2, Ghat2,
                                    F2]])  # projection in original space
    PAfun = Operator(name='FiGFA',
                     mat=[[G1N, Aga]])  # lin. operator for a linear system
    E = np.zeros(dim)
    E[0] = 1  # macroscopic load

    EN = Tensor(name='EN', N=Nbar, shape=(dim, ),
                Fourier=False)  # constant trig. pol.
    EN.set_mean(E)

    x0 = Tensor(N=Nbar, shape=(dim, ),
                Fourier=False)  # initial approximation to solvers
    B = PAfun(-EN)  # right-hand side of linear system

    tic = Timer(name='CG (gradient field)')
    X, info = linear_solver(solver='CG',
                            Afun=PAfun,
                            B=B,
                            x0=x0,
                            par=pars.solver,
                            callback=None)
    tic.measure()

    AH = Aga(X + EN) * (X + EN)
    return Struct(AH=AH, X=X, time=tic.vals[0][0], pars=pars)
Пример #6
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']:
        tim = Timer(name='primal-dual')
        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 = int(pb.dim*(pb.dim+1)/2)
        for iL in range(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)
        tim.measure()

        # POSTPROCESSING
        del Afun, B, E, EN, GN, X
        postprocess(pb, A, mat, solutions, results, primaldual)
# projections in Fourier space
_, hG1N, _ = proj.scalar(pb['solve']['N'], pb['material']['Y'],
                         centered=True, NyqNul=True)
# increasing the projection with zeros to comply with a projection
# on double grid, see Definition 24 in IJNME2016
hG1N = hG1N.enlarge(Nbar)

FN = DFT(name='FN', inverse=False, N=Nbar) # discrete Fourier transform (DFT)
FiN = DFT(name='FiN', inverse=True, N=Nbar) # inverse DFT

G1N = LinOper(name='G1', mat=[[FiN, hG1N, FN]]) # projection in original space
Afun = LinOper(name='FiGFA', mat=[[G1N, A]]) # lin. operator for a linear system

E = np.zeros(dim); E[0] = 1 # macroscopic load
EN = VecTri(name='EN', macroval=E, N=Nbar, Fourier=False) # constant trig. pol.

x0 = VecTri(N=Nbar, d=dim, Fourier=False) # initial approximation to solvers
B = Afun(-EN) # right-hand side of linear system

X, info = linear_solver(solver='CG', Afun=Afun, B=B,
                        x0=x0, par=pb['solver'], callback=None)

print('homogenised properties (component 11) =', A(X + EN)*(X + EN))

if __name__ == "__main__":
    ## plotting of local fields ##################
    X.plot(ind=0, N=N)

print('END')
Пример #8
0
# initial approximation to solvers
x0 = Tensor(N=N, shape=(D, ), Fourier=False)

B = Afun(-EN)  # RHS
B_MS = Afun_MS(-EN)  # RHS

print("""
The linear system is solved with different algorithms:""")
print("""
version #1 :
The solution by Conjugate gradients with zero initial vector; the macroscopic
value occurs on right-hand-side as a load.""")
from ffthompy.general.solver import linear_solver
X, info = linear_solver(solver='CG',
                        Afun=Afun,
                        B=B,
                        x0=x0,
                        par=pb['solver'],
                        callback=None)

print('Homogenised properties (component 11) = {0}'.format(
    A(X + EN) * (X + EN)))

print("""
version #2 :
The solution by Conjugate gradients with initial vector corresponding to
macroscopic value; in this case, the right-hand-side remains zero.
The difference to previous solution is printed:
(X+EN == X2) =""")
X2, info2 = linear_solver(solver='CG',
                          Afun=Afun,
                          B=x0,
Пример #9
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,
                                                    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 = Operator(name='G1', mat=[[FiN, hG1hN + hG1sN, FN]])
    G2N = Operator(name='G2', mat=[[FiN, hG2hN + hG2sN, FN]])

    for primaldual in pb.solve['primaldual']:
        tim = Timer(name='primal-dual')
        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 = Operator(name='FiGFA', mat=[[GN, A]])

        D = int(pb.dim * (pb.dim + 1) / 2)
        for iL in range(D):  # iteration over unitary loads
            E = np.zeros(D)
            E[iL] = 1
            print(('macroscopic load E = ' + str(E)))
            EN = Tensor(name='EN', N=Nbar, shape=(D, ), Fourier=False)
            EN.set_mean(E)
            # initial approximation for solvers
            x0 = EN.zeros_like(name='x0')

            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)
        tim.measure()

        # POSTPROCESSING
        del Afun, B, E, EN, GN, X
        postprocess(pb, A, mat, solutions, results, primaldual)
Пример #10
0
Afun = Operator(name='FiGFA', mat=[[G1N, A]])

# initial approximation to solvers
x0 = Tensor(N=N, shape=(D,), Fourier=False)

B = Afun(-EN) # RHS
B_MS = Afun_MS(-EN) # RHS

print("""
The linear system is solved with different algorithms:""")
print("""
version #1 :
The solution by Conjugate gradients with zero initial vector; the macroscopic
value occurs on right-hand-side as a load.""")
from ffthompy.general.solver import linear_solver
X, info = linear_solver(solver='CG', Afun=Afun, B=B,
                        x0=x0, par=pb['solver'], callback=None)

print('Homogenised properties (component 11) = {0}'.format(A(X+EN)*(X+EN)))

print("""
version #2 :
The solution by Conjugate gradients with initial vector corresponding to
macroscopic value; in this case, the right-hand-side remains zero.
The difference to previous solution is printed:
(X+EN == X2) =""")
X2, info2 = linear_solver(solver='CG', Afun=Afun, B=x0,
                          x0=EN, par=pb['solver'], callback=None)
print(X+EN == X2)

print("""
version #3 :
Пример #11
0
G1N = Operator(name='G1', mat=[[FiN, hG1N,
                                FN]])  # projection in original space
Afun = Operator(name='FiGFA', mat=[[G1N,
                                    A]])  # lin. operator for a linear system

E = np.zeros(dim)
E[0] = 1  # macroscopic load
EN = Tensor(name='EN', N=Nbar, shape=(dim, ),
            Fourier=False)  # constant trig. pol.
EN.set_mean(E)

x0 = Tensor(N=Nbar, shape=(dim, ),
            Fourier=False)  # initial approximation to solvers
B = Afun(-EN)  # right-hand side of linear system

X, info = linear_solver(solver='CG',
                        Afun=Afun,
                        B=B,
                        x0=x0,
                        par=pb['solver'],
                        callback=None)

print('homogenised properties (component 11) =', A(X + EN) * (X + EN))

if __name__ == "__main__":
    ## plotting of local fields ##################
    X.plot(ind=0, N=N)

print('END')