Exemple #1
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])
Exemple #2
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)
Exemple #3
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)
epN_new2 = epN - alp * FiN(hG1(FN(A(epN))))

print("""
Then the resulting vectors are compared to show they are the same:
(epN_new == epN_new2) = """)
print(epN_new == epN_new2)

print("""==============================
Now, we show a solution of homogenization problem for material defined in
problem 'pb' and particular choice of macroscopic value
E =""")
# macroscopic load in Mandel's notation
E = np.zeros(D)
E[0] = 1
EN = Tensor(name='EN', N=N, shape=(D, ), Fourier=False)
EN.set_mean(E)
print(EN)

# definition of reference media according to Moulinec-Suquet
Km = K.mean()
Gm = G.mean()
a = 1 / (Km + 4. / 3 * Gm)
b = 1. / (2 * Gm)

# linear combination of projections corresponding to Moulinec-Suquet scheme
G1N_MS = Operator(name='G1', mat=[[FiN, a * hG1hN + b * hG1sN, FN]])
# linear system with scaled projection
Afun_MS = Operator(name='FiGFA', mat=[[G1N_MS, A]])

# linear system with orthogonal projection
Afun = Operator(name='FiGFA', mat=[[G1N, A]])
Exemple #5
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)
Exemple #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,
                                                    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)
Exemple #7
0
    def test_compatibility(self):
        print('\nChecking compatibility...')
        for dim, fft_form in itertools.product([3], fft_forms):
            N = 5 * np.ones(dim, dtype=np.int)
            F = DFT(inverse=False, N=N, fft_form=fft_form)
            iF = DFT(inverse=True, N=N, fft_form=fft_form)

            # scalar problem
            _, G1l, G2l = scalar(N, Y=np.ones(dim), fft_form=fft_form)
            P1 = Operator(name='P1', mat=[[iF, G1l, F]])
            P2 = Operator(name='P2', mat=[[iF, G2l, F]])
            u = Tensor(name='u',
                       shape=(1, ),
                       N=N,
                       Fourier=False,
                       fft_form=fft_form)
            u.randomize()

            grad_u = grad(u)
            self.assertAlmostEqual(0, (P1(grad_u) - grad_u).norm(),
                                   delta=1e-13)
            self.assertAlmostEqual(0, P2(grad_u).norm(), delta=1e-13)

            e = P1(
                Tensor(name='u',
                       shape=(dim, ),
                       N=N,
                       Fourier=False,
                       fft_form=fft_form).randomize())
            e2 = grad(potential(e))
            self.assertAlmostEqual(0, (e - e2).norm(), delta=1e-13)

            # vectorial problem
            hG = elasticity_large_deformation(N=N,
                                              Y=np.ones(dim),
                                              fft_form=fft_form)
            P1 = Operator(name='P', mat=[[iF, hG, F]])
            u = Tensor(name='u',
                       shape=(dim, ),
                       N=N,
                       Fourier=False,
                       fft_form=fft_form)
            u.randomize()
            grad_u = grad(u)
            val = (P1(grad_u) - grad_u).norm()
            self.assertAlmostEqual(0, val, delta=1e-13)

            e = Tensor(name='F',
                       shape=(dim, dim),
                       N=N,
                       Fourier=False,
                       fft_form=fft_form)
            e = P1(e.randomize())
            e2 = grad(potential(e))
            self.assertAlmostEqual(0, (e - e2).norm(), delta=1e-13)

            # transpose
            P1TT = P1.transpose().transpose()
            self.assertTrue(P1(grad_u) == P1TT(grad_u))

            self.assertTrue(hG == (hG.transpose_left().transpose_left()))
            self.assertTrue(hG == (hG.transpose_right().transpose_right()))

            # vectorial problem - symetric gradient
            hG = elasticity_small_strain(N=N,
                                         Y=np.ones(dim),
                                         fft_form=fft_form)
            P1 = Operator(name='P', mat=[[iF, hG, F]])
            u = Tensor(name='u',
                       shape=(dim, ),
                       N=N,
                       Fourier=False,
                       fft_form=fft_form)
            u.randomize()
            grad_u = symgrad(u)
            val = (P1(grad_u) - grad_u).norm()
            self.assertAlmostEqual(0, val, delta=1e-13)

            e = Tensor(name='strain',
                       shape=(dim, dim),
                       N=N,
                       Fourier=False,
                       fft_form=fft_form)
            e = P1(e.randomize())
            e2 = symgrad(potential(e, small_strain=True))
            self.assertAlmostEqual(0, (e - e2).norm(), delta=1e-13)

            # means
            Fu = F(u)
            E = np.random.random(u.shape)
            u.set_mean(E)
            self.assertAlmostEqual(0, norm(u.mean() - E), delta=1e-13)
            Fu.set_mean(E)
            self.assertAlmostEqual(0, norm(Fu.mean() - E), delta=1e-13)

            # __repr__
            prt.disable()
            print(P1)
            print(u)
            prt.enable()
            self.assertAlmostEqual(0, (P1 == P1.transpose()), delta=1e-13)
        print('...ok')
    def test_compatibility(self):
        print('\nChecking compatibility...')
        for dim, fft_form in itertools.product([3], fft_forms):
            N=5*np.ones(dim, dtype=np.int)
            F=DFT(inverse=False, N=N, fft_form=fft_form)
            iF=DFT(inverse=True, N=N, fft_form=fft_form)

            # scalar problem
            _, G1l, G2l=scalar(N, Y=np.ones(dim), fft_form=fft_form)
            P1=Operator(name='P1', mat=[[iF, G1l, F]])
            P2=Operator(name='P2', mat=[[iF, G2l, F]])
            u=Tensor(name='u', shape=(1,), N=N, Fourier=False, fft_form=fft_form)
            u.randomize()

            grad_u=grad(u)
            self.assertAlmostEqual(0, (P1(grad_u)-grad_u).norm(), delta=1e-13)
            self.assertAlmostEqual(0, P2(grad_u).norm(), delta=1e-13)

            e=P1(Tensor(name='u', shape=(dim,), N=N,
                          Fourier=False, fft_form=fft_form).randomize())
            e2=grad(potential(e))
            self.assertAlmostEqual(0, (e-e2).norm(), delta=1e-13)

            # vectorial problem
            hG=elasticity_large_deformation(N=N, Y=np.ones(dim), fft_form=fft_form)
            P1=Operator(name='P', mat=[[iF, hG, F]])
            u=Tensor(name='u', shape=(dim,), N=N, Fourier=False, fft_form=fft_form)
            u.randomize()
            grad_u=grad(u)
            val=(P1(grad_u)-grad_u).norm()
            self.assertAlmostEqual(0, val, delta=1e-13)

            e=Tensor(name='F', shape=(dim, dim), N=N, Fourier=False, fft_form=fft_form)
            e=P1(e.randomize())
            e2=grad(potential(e))
            self.assertAlmostEqual(0, (e-e2).norm(), delta=1e-13)

            # transpose
            P1TT=P1.transpose().transpose()
            self.assertTrue(P1(grad_u)==P1TT(grad_u))

            self.assertTrue(hG==(hG.transpose_left().transpose_left()))
            self.assertTrue(hG==(hG.transpose_right().transpose_right()))

            # vectorial problem - symetric gradient
            hG=elasticity_small_strain(N=N, Y=np.ones(dim), fft_form=fft_form)
            P1=Operator(name='P', mat=[[iF, hG, F]])
            u=Tensor(name='u', shape=(dim,), N=N, Fourier=False, fft_form=fft_form)
            u.randomize()
            grad_u=symgrad(u)
            val=(P1(grad_u)-grad_u).norm()
            self.assertAlmostEqual(0, val, delta=1e-13)

            e=Tensor(name='strain', shape=(dim, dim), N=N,
                     Fourier=False, fft_form=fft_form)
            e=P1(e.randomize())
            e2=symgrad(potential(e, small_strain=True))
            self.assertAlmostEqual(0, (e-e2).norm(), delta=1e-13)

            # means
            Fu=F(u)
            E=np.random.random(u.shape)
            u.set_mean(E)
            self.assertAlmostEqual(0, norm(u.mean()-E), delta=1e-13)
            Fu.set_mean(E)
            self.assertAlmostEqual(0, norm(Fu.mean()-E), delta=1e-13)

            # __repr__
            prt.disable()
            print(P1)
            print(u)
            prt.enable()
            self.assertAlmostEqual(0, (P1==P1.transpose()), delta=1e-13)
        print('...ok')
# projections in Fourier space
_, hG1N, _ = proj.scalar(pb['solve']['N'], pb['material']['Y'], NyqNul=True, tensor=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 = 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')