Ejemplo n.º 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])
Ejemplo n.º 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)
Ejemplo n.º 3
0
    def test_sparse_solver(self):
        print(
            '\nChecking homogenisation with low-rank tensor approximations...')

        tic = Timer('homogenisation')
        N = 5
        for dim, material, kind in [(2, 0, 0), (2, 3, 1), (3, 1, 1),
                                    (3, 0, 2)]:
            print('dim={}, material={}, kind={}'.format(dim, material, kind))
            pars, pars_sparse = get_default_parameters(dim, N, material, kind)
            pars_sparse.debug = True
            pars_sparse.solver.update(dict(rank=5, maxiter=10))

            prt.disable()

            Aga, Agani, Agas, Aganis = get_material_coef(
                material, pars, pars_sparse)

            if material in [0, 3]:
                resP_Ga = homog_Ga_full_potential(Aga, pars)
                resS_Ga = homog_Ga_sparse(Agas, pars_sparse)

            if material in [1, 2, 4]:
                resP_GaNi = homog_GaNi_full_potential(Agani, Aga, pars)
                resS_GaNi = homog_GaNi_sparse(Aganis, Agas, pars_sparse)

            prt.enable()

            if material in [0, 3]:
                self.assertAlmostEqual(resP_Ga.Fu.mean(), 0)
                self.assertAlmostEqual(resS_Ga.Fu.mean(), 0)
                self.assertAlmostEqual(np.abs(resP_Ga.AH - resS_Ga.AH),
                                       0,
                                       delta=1e-4)

            if material in [1, 2, 4]:
                self.assertAlmostEqual(resP_GaNi.Fu.mean(), 0)
                self.assertAlmostEqual(resS_GaNi.Fu.mean(), 0)
                self.assertAlmostEqual(np.abs(resP_GaNi.AH - resS_GaNi.AH),
                                       0,
                                       delta=1e-4)

        tic.measure()
        print('...ok')
Ejemplo n.º 4
0
def calculate_AH_sparse(Agas, Aniso, FGX, method='full', rank=None, tol=None):
    tic = Timer(name='AH')
    AH = 0.
    if method in ['full']:
        Aga = Agas.full(multype=00)
        FGXf = [T.full() for T in FGX]
        for i in range(FGX.__len__()):
            AH += (Aga * FGXf[i]) * FGXf[i]
            for j in range(FGX.__len__()):
                AH += (Aniso[i, j] * FGXf[i]) * FGXf[j]
    elif method in ['tensorsLowRank']:
        assert (np.linalg.norm(Aniso) < 1e-12)
        for ii in range(FGX.__len__()):
            AH += (Agas * FGX[ii]).truncate(rank=rank, tol=tol).scal(FGX[ii])
    else:
        raise NotImplementedError()

    tic.measure()
    return AH
Ejemplo n.º 5
0
def get_material_coef(material, pars, pars_sparse, ga=True):
    # get configuration settings
    pars, pars_sparse, mat_conf = getMat_conf(material, pars, pars_sparse)

    # generating material coefficients
    mat = Material(mat_conf)
    mats = LowRankMaterial(mat_conf, pars_sparse.kind)

    Agani = mat.get_A_GaNi(pars.N, primaldual='primal')
    Aganis = mats.get_A_GaNi(pars_sparse.N,
                             primaldual='primal',
                             k=pars_sparse.matrank)
    Agani.val = recover_Agani(Agani, Aganis)

    if ga:
        Aga = mat.get_A_Ga(pars.Nbar(pars.N), primaldual='primal')
        Agas = mats.get_A_Ga(pars_sparse.Nbar(pars_sparse.N),
                             primaldual='primal',
                             k=pars_sparse.matrank)
        Aga.val = recover_Aga(Aga, Agas)
    else:
        Aga = None
        Agas = None

    if 'Aniso' in mat_conf:  # workaround for anisotropic material
        Aniso = mat_conf['Aniso']
        Agani.add_mean(Aniso)

        if ga:
            Aga.add_mean(Aniso)

        pars_sparse.update(Struct(Aniso=Aniso))

        tic = Timer('calc_eig')
        eigs = Agani.calc_eigs(symmetric=True)
        tic.measure()

        pars_sparse.solver['alpha'] = 0.5 * (eigs.min() + eigs.max())
    else:
        pars_sparse.solver['alpha'] = 0.5 * (Agani[0, 0].min() +
                                             Agani[0, 0].max())

    return Aga, Agani, Agas, Aganis
Ejemplo n.º 6
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)
Ejemplo n.º 7
0
def minimal_residual_debug(Afun, B, x0=None, par=None):
    fast = par.get('fast')

    M = SparseTensor(kind=B.kind, val=np.ones(B.N.size * [
        3,
    ]), rank=1)  # constant field
    FM = M.fourier().enlarge(B.N)

    res = {'norm_res': [], 'kit': 0}
    if x0 is None:
        x = B * (1. / par['alpha'])
    else:
        x = x0

    if 'norm' not in par:
        norm = lambda X: X.norm(normal_domain=False)

    residuum = (B - Afun(x)).truncate(rank=None, tol=par['tol'], fast=fast)
    res['norm_res'].append(norm(residuum))
    beta = Afun(residuum)

    norm_res = res['norm_res'][res['kit']]

    while (norm_res > par['tol'] and res['kit'] < par['maxiter']):
        res['kit'] += 1
        print('iteration = {}'.format(res['kit']))

        if par['approx_omega']:
            omega = norm_res / norm(beta)  # approximate omega
        else:
            omega = beta.inner(residuum) / norm(beta)**2  # exact formula

        x = (x + residuum * omega)
        x = (-FM * x.mean() + x).truncate(
            rank=par['rank'], tol=par['tol'])  # setting correct mean

        tic = Timer('compute residuum')
        residuum = (B - Afun(x))
        #         residuum=residuum.truncate(rank=2*rank, tol=tol)
        #         residuum=(B-Afun(x)).truncate(rank=rank, tol=tol)
        #         residuum=(B-Afun(x))
        tic.measure()
        tic = Timer('residuum norm')
        norm_res = norm(residuum)
        tic.measure()
        if par['divcrit'] and norm_res > res['norm_res'][-1]:
            break
        res['norm_res'].append(norm_res)

        tic = Timer('truncate residuum')
        #         residuum_for_beta=residuum.truncate(rank=rank, tol=tol)
        #         residuum_for_beta=residuum.truncate(rank=None, tol=1-4)
        tol = min([norm_res / 1e1, par['tol']])
        residuum_for_beta = residuum.truncate(rank=None, tol=tol, fast=fast)
        tic.measure()
        print('tolerance={}, rank={}'.format(tol, residuum_for_beta.r))
        print('residuum_for_beta.r={}'.format(residuum_for_beta.r))
        tic = Timer('compute beta')
        beta = Afun(residuum_for_beta)
        tic.measure()
        pass
    return x, res
Ejemplo n.º 8
0
def homog_GaNi_sparse(Aganis, Agas, pars):
    debug = getattr(pars, 'debug', False)

    N = Aganis.N
    dim = N.__len__()
    hGrad_s = sgrad_tensor(N, pars.Y, kind=pars.kind)

    Aniso = getattr(pars, 'Aniso', np.zeros([dim, dim]))

    # creating constant field in tensorsLowRank tensor
    Es = SparseTensor(name='E',
                      kind=pars.kind,
                      val=np.ones(dim * (3, )),
                      rank=1)
    Es = Es.fourier().enlarge(N).fourier()

    material_law = Material_law(Aganis, Aniso, Es)

    def DFAFGfun_s(X, rank=None, tol=None, fast=False):  # linear operator
        assert (X.Fourier)
        FGX = [(hGrad_s[ii] * X).fourier() for ii in range(dim)]
        AFGFx = material_law(FGX, rank=rank, tol=tol, fast=fast)
        # or in following: Fourier, reduce, truncate
        FAFGFx = [AFGFx[ii].fourier() for ii in range(dim)]
        GFAFGFx = hGrad_s[0] * FAFGFx[0]  # div
        for ii in range(1, dim):
            GFAFGFx += hGrad_s[ii] * FAFGFx[ii]
        GFAFGFx = GFAFGFx.truncate(rank=rank, tol=tol, fast=fast)
        GFAFGFx.name = 'fun(x)'
        return -GFAFGFx

    # R.H.S.
    Bs = hGrad_s[0] * (Aganis * Es).fourier()  # minus from B and from div
    Ps = get_preconditioner_sparse(N, pars)

    def PDFAFGfun_s(Fx,
                    rank=pars.solver['rank'],
                    tol=pars.solver['tol_truncate'],
                    fast=pars.solver['fast']):
        R = DFAFGfun_s(Fx, rank=rank, tol=tol, fast=fast)
        R = Ps * R
        R = R.truncate(rank=rank, tol=tol, fast=fast)
        return R

    PBs = Ps * Bs
    PBs2 = PBs.truncate(tol=pars.rhs_tol, fast=False)
    if debug:
        print('r.h.s. norm = {}; error={}; rank={}'.format(
            np.linalg.norm(PBs.full().val),
            np.linalg.norm(PBs.full().val - PBs2.full().val), PBs2.r))

    PBs = PBs2

    tic = Timer(name=pars.solver['method'])
    Fu, ress = linear_solver_lowrank(pars.solver['method'],
                                     Afun=PDFAFGfun_s,
                                     B=PBs,
                                     par=pars.solver)
    tic.measure()

    print('iterations of solver={}'.format(ress['kit']))
    print('norm of residuum={}'.format(ress['norm_res'][-1]))
    Fu.name = 'Fu'
    print('norm(resP)={}'.format(np.linalg.norm(
        (PBs - PDFAFGfun_s(Fu)).full())))

    if Agas is None:  # GaNi homogenised properties
        print('!!!!! homogenised properties are GaNi only !!!!!')
        FGX = [(hGrad_s[ii] * Fu).fourier() for ii in range(dim)]
        FGX[0] += Es  # adding mean
        AH = calculate_AH_sparse(Aganis, Aniso, FGX, method='full')
    else:
        Nbar = 2 * np.array(N) - 1
        FGX = [((hGrad_s[ii] * Fu).enlarge(Nbar)).fourier()
               for ii in range(dim)]
        Es = SparseTensor(kind=pars.kind, val=np.ones(Nbar), rank=1)
        FGX[0] += Es  # adding mean
        AH = calculate_AH_sparse(Agas, Aniso, FGX, method='full')

    return Struct(AH=AH, e=FGX, solver=ress, Fu=Fu, time=tic.vals[0][0])