Beispiel #1
0
    def test_examples(self):
        N = np.array([10])
        self.assertTrue(np.all(util.interiorpIndexMap(N) == range(1,10)))

        N = np.array([2,2,2,2])
        self.assertTrue(util.interiorpIndexMap(N) == [1+3+9+27])

        N = np.array([2,2,3,2])
        self.assertTrue(np.all(util.interiorpIndexMap(N) == [1+3+9+36, 1+3+9+36+9]))
Beispiel #2
0
    def test_boundarypIndexMap(self):
        N = np.array([3,4,5])
        Np = np.prod(N+1)
        shouldBe = np.setdiff1d(np.arange(Np), util.interiorpIndexMap(N))
        self.assertTrue(np.all(util.boundarypIndexMapLarge(N) == shouldBe))
                     
        boundaryMap = np.array([[True, False],
                                [True, True],
                                [True, True]])
        shouldBe = np.setdiff1d(np.arange(Np), util.interiorpIndexMap(N))
        coords = util.pCoordinates(N)
        shouldBe = np.setdiff1d(shouldBe, np.where(np.logical_and(coords[:,0] == 1,
                                                   np.logical_and(coords[:,1] != 0,
                                                   np.logical_and(coords[:,1] != 1,
                                                   np.logical_and(coords[:,2] != 0,
                                                                  coords[:,2] != 1)))))[0])
        self.assertTrue(np.all(util.boundarypIndexMapLarge(N, boundaryMap) == shouldBe))
        
        boundaryMap = np.array([[True, True],
                                [False, True],
                                [True, True]])
        shouldBe = np.setdiff1d(np.arange(Np), util.interiorpIndexMap(N))
        shouldBe = np.setdiff1d(shouldBe, np.where(np.logical_and(coords[:,0] != 0,
                                                   np.logical_and(coords[:,0] != 1,
                                                   np.logical_and(coords[:,1] == 0,
                                                   np.logical_and(coords[:,2] != 0,
                                                                  coords[:,2] != 1)))))[0])
        self.assertTrue(np.all(util.boundarypIndexMapLarge(N, boundaryMap) == shouldBe))

        boundaryMap = np.array([[True, True],
                                [False, False],
                                [True, True]])
        shouldBe = np.setdiff1d(np.arange(Np), util.interiorpIndexMap(N))
        shouldBe = np.setdiff1d(shouldBe, np.where(np.logical_and(coords[:,0] != 0,
                                                   np.logical_and(coords[:,0] != 1,
                                                   np.logical_and(coords[:,1] == 0,
                                                   np.logical_and(coords[:,2] != 0,
                                                                  coords[:,2] != 1)))))[0])
        shouldBe = np.setdiff1d(shouldBe, np.where(np.logical_and(coords[:,0] != 0,
                                                   np.logical_and(coords[:,0] != 1,
                                                   np.logical_and(coords[:,1] == 1,
                                                   np.logical_and(coords[:,2] != 0,
                                                                  coords[:,2] != 1)))))[0])
        self.assertTrue(np.all(util.boundarypIndexMapLarge(N, boundaryMap) == shouldBe))
def VcLod(pglod, world, Anew, eps, updated=0, numberofcorrectors=5):
    NWorldFine = world.NWorldFine
    NWorldCoarse = world.NWorldCoarse
    NCoarseElement = world.NCoarseElement

    boundaryConditions = world.boundaryConditions
    NpFine = np.prod(NWorldFine + 1)
    NpCoarse = np.prod(NWorldCoarse + 1)

    ##### tolerance = certain ######
    eps = [x for x in eps if x != 0]
    eps.sort()
    epssize = np.size(eps)
    until = int(round((numberofcorrectors / 100. * epssize) + 0.49, 0))
    if epssize != 0:
        until = int(round((until * 256. / epssize) + 0.49, 0))
    tolrev = []
    for i in range(epssize - 1, -1, -1):
        tolrev.append(eps[i])

    if epssize == 0:
        print('nothing to update')
    else:
        if until >= epssize:
            tol = 0
        else:
            tol = tolrev[until]

        vistol, _ = pglod.updateCorrectors(Anew,
                                           tol,
                                           clearFineQuantities=False,
                                           mc=True,
                                           Testing=True)
        updated += np.sum(vistol)
        print(('Updated correctors: ' + str(updated)))

    KFull = pglod.assembleMsStiffnessMatrix()
    MFull = fem.assemblePatchMatrix(NWorldCoarse, world.MLocCoarse)
    free = util.interiorpIndexMap(NWorldCoarse)

    bFull = MFull * f
    KFree = KFull[free][:, free]
    bFree = bFull[free]

    xFree = sparse.linalg.spsolve(KFree, bFree)
    basis = fem.assembleProlongationMatrix(NWorldCoarse, NCoarseElement)

    basisCorrectors = pglod.assembleBasisCorrectors()
    modifiedBasis = basis - basisCorrectors

    xFull = np.zeros(NpCoarse)
    xFull[free] = xFree
    uCoarse = xFull
    uVcLod = modifiedBasis * xFull

    return uVcLod, updated
Beispiel #4
0
def standard_fem(world, N, fine, tau, tot_time_steps, aFine, bFine, f):
    
    # mesh parameters
    NWorldCoarse = np.array([N, N])
    NFine = np.array([fine, fine])
    NCoarseElement = NFine // NWorldCoarse
    NWorldFine = world.NWorldCoarse * world.NCoarseElement
    bc = world.boundaryConditions
    world = World(NWorldCoarse, NCoarseElement, bc)

    NpCoarse = np.prod(NWorldCoarse + 1)    
    basis = fem.assembleProlongationMatrix(NWorldCoarse, NCoarseElement)
    Uo = np.zeros(NpCoarse)
    

    # coarse v^(-1) and v^0
    V = [Uo]
    V.append(Uo)

    # compute ms matrices
    S = fem.assemblePatchMatrix(NWorldFine, world.ALocFine, aFine)
    K = fem.assemblePatchMatrix(NWorldFine, world.ALocFine, bFine)
    M = fem.assemblePatchMatrix(NWorldFine, world.MLocFine)

    free = util.interiorpIndexMap(NWorldCoarse)

    SmsFree = (basis.T * S * basis)[free][:, free]
    KmsFree = (basis.T * K * basis)[free][:, free]
    MmsFree = (basis.T * M * basis)[free][:, free]
    LmsFree = (basis.T * M * f)[free]

    for i in range(tot_time_steps):
        n = i + 1

        # linear system
        A = (1. / (tau ** 2)) * MmsFree + (1. / tau) * SmsFree + KmsFree
        b = LmsFree + (1. / tau) * SmsFree * V[n][free] + (2. / (tau ** 2)) * MmsFree * V[n][free] \
            - (1. / (tau ** 2)) * MmsFree * V[n - 1][free]

        # solve system
        VFree = linalg.linSolve(A, b)
        VFull = np.zeros(NpCoarse)
        VFull[free] = VFree

        # append solution for current time step
        V.append(VFull)
    return basis * V[-1]
def PGsolver(world, ABase, f,k):
    NWorldFine = world.NWorldFine
    NWorldCoarse = world.NWorldCoarse
    NCoarseElement = world.NCoarseElement
    
    boundaryConditions = world.boundaryConditions
    NpFine = np.prod(NWorldFine+1)
    NpCoarse = np.prod(NWorldCoarse+1)
    
    #interpolant
    IPatchGenerator = lambda i, N: interp.L2ProjectionPatchMatrix(i, N, NWorldCoarse, NCoarseElement, boundaryConditions)
    
    #Coefficient (need flatten form)
    aCoef = coef.coefficientFine(NWorldCoarse, NCoarseElement, ABase)

    pglod = pg_pert.PerturbedPetrovGalerkinLOD(aCoef, world, k, IPatchGenerator, 0)
    pglod.originCorrectors(clearFineQuantities=False)

    KFull = pglod.assembleMsStiffnessMatrix()                                    
    MFull = fem.assemblePatchMatrix(NWorldCoarse, world.MLocCoarse)
    free  = util.interiorpIndexMap(NWorldCoarse)                                 

    bFull = MFull*f

    KFree = KFull[free][:,free]
    bFree = bFull[free]

    xFree = sparse.linalg.spsolve(KFree, bFree)

    basis = fem.assembleProlongationMatrix(NWorldCoarse, NCoarseElement)
    basisCorrectors = pglod.assembleBasisCorrectors()
    modifiedBasis = basis - basisCorrectors
    
    xFull = np.zeros(NpCoarse)
    xFull[free] = xFree
    uLodCoarse = xFull
    uLodFine = modifiedBasis*xFull
    
    return uLodCoarse, uLodFine
Beispiel #6
0
    def solve(self, f):
        world = self.world
        KFull = self.assembleMsStiffnessMatrix()
        MFull = fem.assemblePatchMatrix(world.NWorldFine, world.MLocFine)
        free = util.interiorpIndexMap(world.NWorldCoarse)
        basis = fem.assembleProlongationMatrix(world.NWorldCoarse,
                                               world.NCoarseElement)

        bFull = MFull * f
        bFull = basis.T * bFull
        KFree = KFull[free][:, free]
        bFree = bFull[free]

        xFree = sparse.linalg.spsolve(KFree, bFree)
        basisCorrectors = self.assembleBasisCorrectors()
        modifiedBasis = basis - basisCorrectors

        NpCoarse = np.prod(world.NWorldCoarse + 1)
        xFull = np.zeros(NpCoarse)
        xFull[free] = xFree
        uLodCoarse = xFull
        uLodFine = modifiedBasis * xFull

        return uLodFine, uLodCoarse, basis
def result(pglod, world, A, R, f, k, String):
    print(("-------------- " + String + " ---------------"))

    NWorldFine = world.NWorldFine
    NWorldCoarse = world.NWorldCoarse
    NCoarseElement = world.NCoarseElement

    boundaryConditions = world.boundaryConditions
    NpFine = np.prod(NWorldFine + 1)
    NpCoarse = np.prod(NWorldCoarse + 1)

    # new Coefficient
    ANew = R.flatten()
    Anew = coef.coefficientFine(NWorldCoarse, NCoarseElement, ANew)

    start_solver = timeit.default_timer()

    # reference solution
    f_fine = np.ones(NpFine)
    uFineFem, AFine, MFine = femsolver.solveFine(world, ANew, f_fine, None,
                                                 boundaryConditions)
    print(('Runtime: it took {} sec to compute the reference solution'.format(
        timeit.default_timer() - start_solver)))

    start_solve_system = timeit.default_timer()
    # worst solution
    KFull = pglod.assembleMsStiffnessMatrix()
    MFull = fem.assemblePatchMatrix(NWorldCoarse, world.MLocCoarse)
    free = util.interiorpIndexMap(NWorldCoarse)

    bFull = MFull * f
    KFree = KFull[free][:, free]
    bFree = bFull[free]

    xFree = sparse.linalg.spsolve(KFree, bFree)

    basis = fem.assembleProlongationMatrix(NWorldCoarse, NCoarseElement)

    basisCorrectors = pglod.assembleBasisCorrectors()
    modifiedBasis = basis - basisCorrectors

    xFull = np.zeros(NpCoarse)
    xFull[free] = xFree
    uCoarse = xFull
    uLodFine = modifiedBasis * xFull

    print(('Runtime: It took {} sec to apply LOD with given correctors'.format(
        timeit.default_timer() - start_solve_system)))
    uLodFineWorst = uLodFine

    # energy error
    errorworst = np.sqrt(
        np.dot(uFineFem - uLodFineWorst, AFine * (uFineFem - uLodFineWorst)))

    start_runtime = timeit.default_timer()
    # tolerance = 0
    vis, eps = pglod.updateCorrectors(Anew,
                                      0,
                                      clearFineQuantities=False,
                                      Computing=False)

    print(('Runtime: It took {} sec to compute the error indicators.'.format(
        timeit.default_timer() - start_runtime)))

    PotentialCorrectors = np.sum(vis)
    elemente = np.arange(np.prod(NWorldCoarse))

    # identify tolerances
    epsnozero = [x for x in eps if x != 0]

    assert (np.size(epsnozero) != 0)

    mini = np.min(epsnozero)
    minilog = int(round(np.log10(mini) - 0.49))
    epsnozero.append(10**(minilog))
    ToleranceListcomplete = []
    for i in range(0, int(np.size(epsnozero))):
        ToleranceListcomplete.append(epsnozero[i])

    ToleranceListcomplete.sort()
    ToleranceListcomplete = np.unique(ToleranceListcomplete)

    # with tolerance
    errorplotinfo = []
    tolerancesafe = []
    errorBest = []
    errorWorst = []
    recomputefractionsafe = []
    recomputefraction = 0
    Correctors = 0
    runtime = []
    total_time = 0
    leng = np.size(ToleranceListcomplete)
    for k in range(leng - 1, -1, -1):
        tol = ToleranceListcomplete[k]
        print(
            (" --- " + str(-k + leng) + "/" + str(leng) + " --- Tolerance: " +
             str(round(tol, 5)) + " in " + String + " ---- "))

        start_runtime = timeit.default_timer()
        vistol, time_to_compute = pglod.updateCorrectors(
            Anew, tol, clearFineQuantities=False, Testing=True, runtime=True)
        total_time += timeit.default_timer() - start_runtime - time_to_compute
        runtime.append(total_time)

        Correctors += np.sum(vistol)

        recomputefraction += float(np.sum(vistol)) / PotentialCorrectors * 100
        recomputefractionsafe.append(recomputefraction)

        KFull = pglod.assembleMsStiffnessMatrix()
        MFull = fem.assemblePatchMatrix(NWorldCoarse, world.MLocCoarse)
        free = util.interiorpIndexMap(NWorldCoarse)

        bFull = MFull * f
        KFree = KFull[free][:, free]
        bFree = bFull[free]

        xFree = sparse.linalg.spsolve(KFree, bFree)
        basis = fem.assembleProlongationMatrix(NWorldCoarse, NCoarseElement)

        basisCorrectors = pglod.assembleBasisCorrectors()

        modifiedBasis = basis - basisCorrectors

        xFull = np.zeros(NpCoarse)
        xFull[free] = xFree
        uCoarse = xFull
        uLodFine = modifiedBasis * xFull

        # energy error
        errortol = np.sqrt(
            np.dot(uFineFem - uLodFine, AFine * (uFineFem - uLodFine)))

        errorplotinfo.append(errortol)
        tolerancesafe.append(tol)

    # 100% updating
    uLodFinebest = uLodFine
    errorbest = np.sqrt(
        np.dot(uFineFem - uLodFinebest, AFine * (uFineFem - uLodFinebest)))

    print(('Runtime: Total time of updating: {} sec.'.format(total_time)))
    for k in range(leng - 1, -1, -1):
        errorBest.append(errorbest)
        errorWorst.append(errorworst)

    return vis, eps, PotentialCorrectors, recomputefractionsafe, errorplotinfo, errorWorst, errorBest, runtime
Beispiel #8
0
    UFine.append(ms_basis * Uo)

    # initial value w^0
    Wo = np.zeros(NpFine)
    WFine = [Wo]

    # compute ms matrices
    S = fem.assemblePatchMatrix(NWorldFine, world.ALocFine, aFine)
    K = fem.assemblePatchMatrix(NWorldFine, world.ALocFine, bFine)
    M = fem.assemblePatchMatrix(NWorldFine, world.MLocFine)

    SmsFull = ms_basis.T * S * ms_basis
    KmsFull = ms_basis.T * K * ms_basis
    MmsFull = ms_basis.T * M * ms_basis

    free = util.interiorpIndexMap(NWorldCoarse)

    SmsFree = SmsFull[free][:, free]
    KmsFree = KmsFull[free][:, free]
    MmsFree = MmsFull[free][:, free]

    boundaryMap = boundaryConditions == 0
    fixedFine = util.boundarypIndexMap(NWorldFine, boundaryMap)
    freeFine = np.setdiff1d(np.arange(NpFine), fixedFine)

    # load vector
    f = np.ones(NpFine)
    LFull = M * f
    LmsFull = ms_basis.T * LFull
    LmsFree = LmsFull[free]
Beispiel #9
0
def rb_method_sparse_stop(world, N, fine, tau, tot_time_steps, k, aFine, bFine, f, no_rb_vecs, TOL=None):

    # coarse mesh parameters
    NWorldCoarse = np.array([N, N])
    NFine = np.array([fine, fine])
    NpFine = np.prod(NFine + 1)
    NCoarseElement = NFine // NWorldCoarse
    NWorldFine = world.NWorldCoarse * world.NCoarseElement
    bc = world.boundaryConditions
    world = World(NWorldCoarse, NCoarseElement, bc)

    if TOL is None:
        TOL = 1e-6

    NpCoarse = np.prod(NWorldCoarse + 1)

    def IPatchGenerator(i, N):
        return interp.L2ProjectionPatchMatrix(i, N, NWorldCoarse, NCoarseElement, bc)

    b_coef = coef.coefficientFine(NWorldCoarse, NCoarseElement, bFine)
    a_coef = coef.coefficientFine(NWorldCoarse, NCoarseElement, aFine / tau)

    # compute basis correctors
    lod = lod_wave.LodWave(b_coef, world, k, IPatchGenerator, a_coef)
    lod.compute_basis_correctors()

    # compute ms basis
    basis = fem.assembleProlongationMatrix(NWorldCoarse, NCoarseElement)
    basis_correctors = lod.assembleBasisCorrectors()
    ms_basis = basis - basis_correctors

    fs_solutions_new = [sparse.csc_matrix(np.zeros_like(ms_basis.toarray())) for i in range(tot_time_steps)]
    for node in range(NpCoarse):
        prev_fs_sol_new = ms_basis[:, node]
        snapshots = []
        
        for time_step in range(no_rb_vecs):
            print('Calculating correction at N = %d, node = %d/%d, time_step = %d' % (N, node, NpCoarse, time_step))
            node_index_arr = compute_2d_node(world.NWorldCoarse, node)
            ecT = lod_node.nodeCorrector(world, k, node_index_arr)

            b_patch = b_coef.localize(ecT.iPatchWorldCoarse, ecT.NPatchCoarse)
            a_patch = a_coef.localize(ecT.iPatchWorldCoarse, ecT.NPatchCoarse)

            IPatch = IPatchGenerator(ecT.iPatchWorldCoarse, ecT.NPatchCoarse)

            fs_list = ecT.compute_localized_node_correction_test(b_patch, a_patch, IPatch, prev_fs_sol_new, node)
            prev_fs_sol_new = sparse.csr_matrix(fs_list).T
            fs_solutions_new[time_step][:, node] = prev_fs_sol_new
            snapshots.append(fs_list)

            V = sparse.csc_matrix(gram_schmidt_rb(snapshots, TOL))
            if V.get_shape()[0] == time_step:
                break

        for i in range(time_step + 1, tot_time_steps):
            fs_solutions_new[i][:, node] = sparse.csc_matrix(V.T * ecT.compute_rb_node_correction_test(b_patch, a_patch, IPatch, fs_solutions_new[i-1][:, node], V)).T


    # initial value
    Uo = np.zeros(NpCoarse)

    # coarse v^(-1) and v^0
    V = [Uo]
    V.append(Uo)

    # compute ms matrices
    S = fem.assemblePatchMatrix(NWorldFine, world.ALocFine, aFine)
    K = fem.assemblePatchMatrix(NWorldFine, world.ALocFine, bFine)
    M = fem.assemblePatchMatrix(NWorldFine, world.MLocFine)

    free = util.interiorpIndexMap(NWorldCoarse)

    SmsFree = (ms_basis.T * S * ms_basis)[free][:, free]
    KmsFree = (ms_basis.T * K * ms_basis)[free][:, free]
    MmsFree = (ms_basis.T * M * ms_basis)[free][:, free]

    # load vector
    f = np.ones(NpFine)
    LmsFree = (ms_basis.T * M * f)[free]

    RmsFreeList = []
    for i in range(tot_time_steps):
        n = i + 1

        # linear system
        A = (1. / (tau ** 2)) * MmsFree + (1. / tau) * SmsFree + KmsFree
        b = LmsFree + (1. / tau) * SmsFree * V[n][free] + (2. / (tau ** 2)) * MmsFree * V[n][free] \
            - (1. / (tau ** 2)) * MmsFree * V[n - 1][free]

        # store ms matrix R^{ms',h}_{H,i,k}
        RmsFull = ms_basis.T * S * sparse.csc_matrix(fs_solutions_new[i])
        RmsFree = RmsFull[free][:, free]
        RmsFreeList.append(RmsFree)

        # add sum to linear system
        if i != 0:
            for j in range(i):
                b += (1. / tau) * RmsFreeList[j] * V[n - 1 - j][free]

        # solve system
        VFree = linalg.linSolve(A, b)
        VFull = np.zeros(NpCoarse)
        VFull[free] = VFree

        # append solution for current time step
        V.append(VFull)
    VFine = ms_basis * V[-1]

    WFine = 0
    for j in range(tot_time_steps):
        WFine += sparse.csc_matrix(fs_solutions_new[j]) * V[n - j]

    return VFine + WFine, ms_basis * Uo
Beispiel #10
0
def standard_method(world, N, fine, tau, tot_time_steps, k, aFine, bFine, f):
    
    # coarse mesh parameters
    NWorldCoarse = np.array([N, N])
    NFine = np.array([fine, fine])
    NpFine = np.prod(NFine + 1)
    NCoarseElement = NFine // NWorldCoarse
    NWorldFine = world.NWorldCoarse * world.NCoarseElement
    bc = world.boundaryConditions
    world = World(NWorldCoarse, NCoarseElement, bc)

    NpCoarse = np.prod(NWorldCoarse + 1)

    def IPatchGenerator(i, N):
        return interp.L2ProjectionPatchMatrix(i, N, NWorldCoarse, NCoarseElement, bc)

    b_coef = coef.coefficientFine(NWorldCoarse, NCoarseElement, bFine)
    a_coef = coef.coefficientFine(NWorldCoarse, NCoarseElement, aFine / tau)

    # compute basis correctors
    lod = lod_wave.LodWave(b_coef, world, k, IPatchGenerator, a_coef)
    lod.compute_basis_correctors()

    # compute ms basis
    basis = fem.assembleProlongationMatrix(NWorldCoarse, NCoarseElement)
    basis_correctors = lod.assembleBasisCorrectors()
    ms_basis = basis - basis_correctors

    # compute finescale solution correctors
    prev_fs_sol = ms_basis
    fs_solutions_new = []
    for i in range(tot_time_steps):
        print('Calculating correction at N = %d, i = %d' % (N, i))

        # solve localized system
        lod = lod_wave.LodWave(b_coef, world, k, IPatchGenerator, a_coef, prev_fs_sol)
        lod.solve_fs_system(localized=True)

        # store sparse solution
        prev_fs_sol = sparse.csc_matrix(np.array(np.column_stack(lod.fs_list)))
        fs_solutions_new.append(prev_fs_sol)

    # initial value
    Uo = np.zeros(NpCoarse)

    # coarse v^(-1) and v^0
    V = [Uo]
    V.append(Uo)

    # compute ms matrices
    S = fem.assemblePatchMatrix(NWorldFine, world.ALocFine, aFine)
    K = fem.assemblePatchMatrix(NWorldFine, world.ALocFine, bFine)
    M = fem.assemblePatchMatrix(NWorldFine, world.MLocFine)

    free = util.interiorpIndexMap(NWorldCoarse)

    SmsFree = (ms_basis.T * S * ms_basis)[free][:, free]
    KmsFree = (ms_basis.T * K * ms_basis)[free][:, free]
    MmsFree = (ms_basis.T * M * ms_basis)[free][:, free]

    # load vector
    f = np.ones(NpFine)
    LmsFree = (ms_basis.T * M * f)[free]

    RmsFreeList = []
    for i in range(tot_time_steps):
        n = i + 1

        # linear system
        A = (1. / (tau ** 2)) * MmsFree + (1. / tau) * SmsFree + KmsFree
        b = LmsFree + (1. / tau) * SmsFree * V[n][free] + (2. / (tau ** 2)) * MmsFree * V[n][free] \
            - (1. / (tau ** 2)) * MmsFree * V[n - 1][free]

        # store ms matrix R^{ms',h}_{H,i,k}
        RmsFull = ms_basis.T * S * sparse.csc_matrix(fs_solutions_new[i])
        RmsFree = RmsFull[free][:, free]
        RmsFreeList.append(RmsFree)

        # add sum to linear system
        if i != 0:
            for j in range(i):
                b += (1. / tau) * RmsFreeList[j] * V[n - 1 - j][free]

        # solve system
        VFree = linalg.linSolve(A, b)
        VFull = np.zeros(NpCoarse)
        VFull[free] = VFree

        # append solution for current time step
        V.append(VFull)
    VFine = ms_basis * V[-1]

    WFine = 0
    for j in range(tot_time_steps):
        WFine += sparse.csc_matrix(fs_solutions_new[j]) * V[n - j]

    return VFine + WFine, ms_basis * Uo
Beispiel #11
0
def standard_lod(world, N, fine, tau, tot_time_steps, k, aFine, bFine, f, damp_corr=False, both_coef=False):
    
    # mesh parameters
    NWorldCoarse = np.array([N, N])
    NFine = np.array([fine, fine])
    NCoarseElement = NFine // NWorldCoarse
    NWorldFine = world.NWorldCoarse * world.NCoarseElement
    bc = world.boundaryConditions
    world = World(NWorldCoarse, NCoarseElement, bc)

    def IPatchGenerator(i, N):
        return interp.L2ProjectionPatchMatrix(i, N, NWorldCoarse, NCoarseElement, bc)

    b_coef = coef.coefficientFine(NWorldCoarse, NCoarseElement, bFine)
    a_coef = coef.coefficientFine(NWorldCoarse, NCoarseElement, aFine / tau)

    NpCoarse = np.prod(NWorldCoarse + 1)    
    basis = fem.assembleProlongationMatrix(NWorldCoarse, NCoarseElement)

    # compute basis correctors
    if damp_corr:
        b_coef = coef.coefficientFine(NWorldCoarse, NCoarseElement, np.zeros_like(bFine))
        a_coef = coef.coefficientFine(NWorldCoarse, NCoarseElement, aFine / tau)
    elif both_coef:
        b_coef = coef.coefficientFine(NWorldCoarse, NCoarseElement, bFine)
        a_coef = coef.coefficientFine(NWorldCoarse, NCoarseElement, aFine)
    else:
        a_coef = coef.coefficientFine(NWorldCoarse, NCoarseElement, np.zeros_like(aFine))
        b_coef = coef.coefficientFine(NWorldCoarse, NCoarseElement, bFine)
    
    lod = lod_wave.LodWave(b_coef, world, k, IPatchGenerator, a_coef)
    lod.compute_basis_correctors()

    # compute ms basis
    basis = fem.assembleProlongationMatrix(NWorldCoarse, NCoarseElement)
    basis_correctors = lod.assembleBasisCorrectors()
    mod_basis = basis - basis_correctors

    Uo = np.zeros(NpCoarse)

    # coarse v^(-1) and v^0
    V = [Uo]
    V.append(Uo)

    # compute ms matrices
    S = fem.assemblePatchMatrix(NWorldFine, world.ALocFine, aFine)
    K = fem.assemblePatchMatrix(NWorldFine, world.ALocFine, bFine)
    M = fem.assemblePatchMatrix(NWorldFine, world.MLocFine)

    free = util.interiorpIndexMap(NWorldCoarse)

    SmsFree = (mod_basis.T * S * mod_basis)[free][:, free]
    KmsFree = (mod_basis.T * K * mod_basis)[free][:, free]
    MmsFree = (mod_basis.T * M * mod_basis)[free][:, free]
    LmsFree = (mod_basis.T * M * f)[free]

    for i in range(tot_time_steps):
        n = i + 1

        # linear system
        A = (1. / (tau ** 2)) * MmsFree + (1. / tau) * SmsFree + KmsFree
        b = LmsFree + (1. / tau) * SmsFree * V[n][free] + (2. / (tau ** 2)) * MmsFree * V[n][free] \
            - (1. / (tau ** 2)) * MmsFree * V[n - 1][free]

        # solve system
        VFree = linalg.linSolve(A, b)
        VFull = np.zeros(NpCoarse)
        VFull[free] = VFree

        # append solution for current time step
        V.append(VFull)
    return mod_basis * V[-1]
Beispiel #12
0
    def test_1d(self):
        # Example from Peterseim, Variational Multiscale Stabilization and the Exponential Decay of correctors, p. 2
        # Two modifications: A with minus and u(here) = 1/4*u(paper).
        NFine = np.array([3200])
        NpFine = np.prod(NFine + 1)
        NList = [10, 20, 40, 80, 160]
        epsilon = 1024. / NFine
        epsilon = 1. / 320
        k = 2

        pi = np.pi

        xt = util.tCoordinates(NFine).flatten()
        xp = util.pCoordinates(NFine).flatten()
        #aFine = (2 + np.cos(2*pi*xt/epsilon))**(-1)
        aFine = (2 - np.cos(2 * pi * xt / epsilon))**(-1)

        uSol = 4 * (xp - xp**2) - 4 * epsilon * (
            1 / (4 * pi) * np.sin(2 * pi * xp / epsilon) - 1 /
            (2 * pi) * xp * np.sin(2 * pi * xp / epsilon) - epsilon /
            (4 * pi**2) * np.cos(2 * pi * xp / epsilon) + epsilon /
            (4 * pi**2))

        uSol = uSol / 4

        previousErrorCoarse = np.inf
        previousErrorFine = np.inf

        for N in NList:
            NWorldCoarse = np.array([N])
            NCoarseElement = NFine / NWorldCoarse
            boundaryConditions = np.array([[0, 0]])
            world = World(NWorldCoarse, NCoarseElement, boundaryConditions)

            xpCoarse = util.pCoordinates(NWorldCoarse).flatten()

            NpCoarse = np.prod(NWorldCoarse + 1)

            IPatchGenerator = lambda i, N: interp.L2ProjectionPatchMatrix(
                i, N, NWorldCoarse, NCoarseElement, boundaryConditions)
            aCoef = coef.coefficientFine(NWorldCoarse, NCoarseElement, aFine)

            pglod = pg.PetrovGalerkinLOD(world, k, IPatchGenerator, 0)
            pglod.updateCorrectors(aCoef, clearFineQuantities=False)

            KFull = pglod.assembleMsStiffnessMatrix()
            MFull = fem.assemblePatchMatrix(NWorldCoarse, world.MLocCoarse)

            free = util.interiorpIndexMap(NWorldCoarse)

            f = np.ones(NpCoarse)
            bFull = MFull * f

            KFree = KFull[free][:, free]
            bFree = bFull[free]

            xFree = sparse.linalg.spsolve(KFree, bFree)

            basis = fem.assembleProlongationMatrix(NWorldCoarse,
                                                   NCoarseElement)
            basisCorrectors = pglod.assembleBasisCorrectors()
            modifiedBasis = basis - basisCorrectors
            xFull = np.zeros(NpCoarse)
            xFull[free] = xFree
            uLodCoarse = basis * xFull
            uLodFine = modifiedBasis * xFull

            AFine = fem.assemblePatchMatrix(NFine, world.ALocFine, aFine)
            MFine = fem.assemblePatchMatrix(NFine, world.MLocFine)

            newErrorCoarse = np.sqrt(
                np.dot(uSol - uLodCoarse, MFine * (uSol - uLodCoarse)))
            newErrorFine = np.sqrt(
                np.dot(uSol - uLodFine, AFine * (uSol - uLodFine)))

            self.assertTrue(newErrorCoarse < previousErrorCoarse)
            self.assertTrue(newErrorFine < previousErrorFine)
Beispiel #13
0
    def test_1d_toReference(self):
        NWorldFine = np.array([200])
        NWorldCoarse = np.array([10])
        NCoarseElement = NWorldFine / NWorldCoarse
        boundaryConditions = np.array([[0, 0]])
        world = World(NWorldCoarse, NCoarseElement, boundaryConditions)

        NpFine = np.prod(NWorldFine + 1)
        NtFine = np.prod(NWorldFine)
        NpCoarse = np.prod(NWorldCoarse + 1)

        aBase = np.zeros(NtFine)
        aBase[:90] = 1
        aBase[90:] = 2

        k = 10

        IPatchGenerator = lambda i, N: interp.L2ProjectionPatchMatrix(
            i, N, NWorldCoarse, NCoarseElement, boundaryConditions)
        aCoef = coef.coefficientFine(NWorldCoarse, NCoarseElement, aBase)

        pglod = pg.PetrovGalerkinLOD(world, k, IPatchGenerator, 0)
        pglod.updateCorrectors(aCoef, clearFineQuantities=False)

        KmsFull = pglod.assembleMsStiffnessMatrix()
        KFull = pglod.assembleStiffnessMatrix()
        MFull = fem.assemblePatchMatrix(NWorldCoarse, world.MLocCoarse)

        free = util.interiorpIndexMap(NWorldCoarse)

        coords = util.pCoordinates(NWorldCoarse)
        g = 1 - coords[:, 0]
        bFull = -KmsFull * g

        KmsFree = KmsFull[free][:, free]
        bFree = bFull[free]

        xFree = sparse.linalg.spsolve(KmsFree, bFree)

        basis = fem.assembleProlongationMatrix(NWorldCoarse, NCoarseElement)
        basisCorrectors = pglod.assembleBasisCorrectors()
        modifiedBasis = basis - basisCorrectors
        xFull = np.zeros(NpCoarse)
        xFull[free] = xFree
        uLodCoarse = basis * (xFull + g)
        uLodFine = modifiedBasis * (xFull + g)

        coordsFine = util.pCoordinates(NWorldFine)
        gFine = 1 - coordsFine[:, 0]
        uFineFull, AFine, _ = femsolver.solveFine(world, aBase, None, -gFine,
                                                  boundaryConditions)
        uFineFull += gFine

        errorFine = np.sqrt(
            np.dot(uFineFull - uLodFine, AFine * (uFineFull - uLodFine)))
        self.assertTrue(np.isclose(errorFine, 0))

        # Also compute upscaled solution and compare with uFineFull
        uLodFineUpscaled = basis * (xFull + g) - pglod.computeCorrection(
            ARhsFull=basis * (xFull + g))
        self.assertTrue(np.allclose(uLodFineUpscaled, uLodFine))
Beispiel #14
0
        def test_1d_core(mapper):
            # Example from Peterseim, Variational Multiscale Stabilization and the Exponential Decay of correctors, p. 2
            # Two modifications: A with minus and u(here) = 1/4*u(paper).
            NFine = np.array([3200])
            NpFine = np.prod(NFine + 1)
            NList = [10, 20, 40, 80, 160]
            epsilon = 1. / 320
            k = 2

            pi = np.pi

            xt = util.tCoordinates(NFine).flatten()
            xp = util.pCoordinates(NFine).flatten()
            aFine = (2 - np.cos(2 * pi * xt / epsilon))**(-1)

            uSol = 4 * (xp - xp**2) - 4 * epsilon * (
                1 / (4 * pi) * np.sin(2 * pi * xp / epsilon) - 1 /
                (2 * pi) * xp * np.sin(2 * pi * xp / epsilon) - epsilon /
                (4 * pi**2) * np.cos(2 * pi * xp / epsilon) + epsilon /
                (4 * pi**2))

            uSol = uSol / 4

            previousErrorCoarse = np.inf
            previousErrorFine = np.inf

            for N in NList:
                NWorldCoarse = np.array([N])
                NCoarseElement = NFine // NWorldCoarse
                boundaryConditions = np.array([[0, 0]])
                world = World(NWorldCoarse, NCoarseElement, boundaryConditions)

                xpCoarse = util.pCoordinates(NWorldCoarse).flatten()

                def computeKmsij(TInd):
                    patch = Patch(world, k, TInd)
                    IPatch = lambda: interp.L2ProjectionPatchMatrix(
                        patch, boundaryConditions)
                    aPatch = lambda: coef.localizeCoefficient(patch, aFine)

                    correctorsList = lod.computeBasisCorrectors(
                        patch, IPatch, aPatch)
                    csi = lod.computeBasisCoarseQuantities(
                        patch, correctorsList, aPatch)
                    return patch, correctorsList, csi.Kmsij

                # Use mapper to distribute computations (mapper could be the 'map' built-in or e.g. an ipyparallel map)
                patchT, correctorsListT, KmsijT = zip(
                    *mapper(computeKmsij, range(world.NtCoarse)))

                KFull = pglod.assembleMsStiffnessMatrix(world, patchT, KmsijT)
                MFull = fem.assemblePatchMatrix(NWorldCoarse, world.MLocCoarse)

                free = util.interiorpIndexMap(NWorldCoarse)

                f = np.ones(world.NpCoarse)
                bFull = MFull * f

                KFree = KFull[free][:, free]
                bFree = bFull[free]

                xFree = sparse.linalg.spsolve(KFree, bFree)

                basis = fem.assembleProlongationMatrix(NWorldCoarse,
                                                       NCoarseElement)
                basisCorrectors = pglod.assembleBasisCorrectors(
                    world, patchT, correctorsListT)
                modifiedBasis = basis - basisCorrectors
                xFull = np.zeros(world.NpCoarse)
                xFull[free] = xFree
                uLodCoarse = basis * xFull
                uLodFine = modifiedBasis * xFull

                AFine = fem.assemblePatchMatrix(NFine, world.ALocFine, aFine)
                MFine = fem.assemblePatchMatrix(NFine, world.MLocFine)

                newErrorCoarse = np.sqrt(
                    np.dot(uSol - uLodCoarse, MFine * (uSol - uLodCoarse)))
                newErrorFine = np.sqrt(
                    np.dot(uSol - uLodFine, AFine * (uSol - uLodFine)))

                self.assertTrue(newErrorCoarse < previousErrorCoarse)
                self.assertTrue(newErrorFine < previousErrorFine)
Beispiel #15
0
    def test_trivials(self):
        N = np.array([1])
        self.assertTrue(np.size(util.interiorpIndexMap(N)) == 0)

        N = np.array([2])
        self.assertTrue(np.all(util.interiorpIndexMap(N) == [1]))