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]))
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
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
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
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]
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
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
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]
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)
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))
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)
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]))