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 solveCoarse_fem(world, aFine, bFine, MbFine, U, tau, boundaryConditions, i): NWorldCoarse = world.NWorldCoarse NWorldFine = world.NWorldCoarse * world.NCoarseElement NCoarseElement = world.NCoarseElement NpFine = np.prod(NWorldFine + 1) NpCoarse = np.prod(NWorldCoarse + 1) if MbFine is None: MbFine = np.zeros(NpFine) boundaryMap = boundaryConditions == 0 fixedCoarse = util.boundarypIndexMap(NWorldCoarse, boundaryMap=boundaryMap) freeCoarse = np.setdiff1d(np.arange(NpCoarse), fixedCoarse) AFine = fem.assemblePatchMatrix(NWorldFine, world.ALocFine, aFine) BFine = fem.assemblePatchMatrix(NWorldFine, world.ALocFine, bFine) MFine = fem.assemblePatchMatrix(NWorldFine, world.MLocFine) bFine = MFine * MbFine basis = fem.assembleProlongationMatrix(NWorldCoarse, NCoarseElement) ACoarse = basis.T * (AFine * basis) BCoarse = basis.T * (BFine * basis) MCoarse = basis.T * (MFine * basis) bCoarse = basis.T * bFine ACoarseFree = ACoarse[freeCoarse][:, freeCoarse] BCoarseFree = BCoarse[freeCoarse][:, freeCoarse] MCoarseFree = MCoarse[freeCoarse][:, freeCoarse] bCoarseFree = bCoarse[freeCoarse] A = (1. / tau**2) * MCoarseFree + (1. / tau) * ACoarseFree + BCoarseFree if i == 0: b = bCoarseFree + (1. / tau) * ACoarseFree * U[i][freeCoarse] + ( 1. / tau) * MCoarseFree * ((2. / tau) * U[i][freeCoarse]) else: b = bCoarseFree + (1. / tau) * ACoarseFree * U[i][freeCoarse] + ( 1. / tau) * MCoarseFree * ((2. / tau) * U[i][freeCoarse] - (1. / tau) * U[i - 1][freeCoarse]) uCoarseFree = linalg.linSolve(A, b) uCoarseFull = np.zeros(NpCoarse) uCoarseFull[freeCoarse] = uCoarseFree uCoarseFull = uCoarseFull return uCoarseFull
def reference_sol(world, fine, tau, tot_time_steps, init_val, aFine, bFine, f): NFine = np.array([fine, fine]) NpFine = np.prod(NFine + 1) bc = world.boundaryConditions NWorldFine = world.NWorldCoarse * world.NCoarseElement # set initial value U = [init_val] U.append(init_val) # assemble matrices S = fem.assemblePatchMatrix(NWorldFine, world.ALocFine, aFine) K = fem.assemblePatchMatrix(NWorldFine, world.ALocFine, bFine) M = fem.assemblePatchMatrix(NWorldFine, world.MLocFine) # find free indices boundary_map = bc == 0 fixed = util.boundarypIndexMap(NWorldFine, boundary_map) free = np.setdiff1d(np.arange(NpFine), fixed) # create free matrices Sf = S[free][:, free] Kf = K[free][:, free] Mf = M[free][:, free] Lf = (M * f)[free] for i in range(tot_time_steps): # reference system A = (1. / (tau ** 2)) * Mf + (1. / tau) * Sf + Kf b = Lf + (1. / tau) * Sf * U[1][free] + (2. / (tau ** 2)) * Mf * U[1][free] - \ (1. / (tau ** 2)) * Mf * U[0][free] # solve system UFineFree = linalg.linSolve(A, b) UFineFull = np.zeros(NpFine) UFineFull[free] = UFineFree # append solution U[0] = U[1] U[1] = UFineFull return U[-1]
def compute_rb_node_correction_test(self, b_patch, a_patch, IPatch, prev_fs_sol, V): world = self.world NCoarseElement = world.NCoarseElement NPatchCoarse = self.NPatchCoarse NPatchFine = NPatchCoarse * NCoarseElement NtFine = np.prod(NPatchFine) NpCoarse = np.prod(NPatchCoarse + 1) NpFine = np.prod(NPatchFine + 1) iPatchWorldCoarse = self.iPatchWorldCoarse iPatchWorldFine = iPatchWorldCoarse * NCoarseElement patchpIndexMap = util.lowerLeftpIndexMap(NPatchFine, world.NWorldFine) patchpStartIndex = util.convertpCoordIndexToLinearIndex( world.NWorldFine, iPatchWorldFine) patch_indices = patchpStartIndex + patchpIndexMap b_patch = b_patch.aFine a_patch = a_patch.aFine assert (np.size(b_patch) == NtFine) SPatchFull = fem.assemblePatchMatrix(NPatchFine, world.ALocFine, b_patch) KPatchFull = fem.assemblePatchMatrix(NPatchFine, world.ALocFine, a_patch) bPatchFullList = [] bPatchFull = np.zeros(len((V.todense()))) V = V[:, patch_indices] bPatchFull += prev_fs_sol[patch_indices].T * KPatchFull * V.T bPatchFullList.append(bPatchFull) SPatchFull = V * SPatchFull * V.T KPatchFull = V * KPatchFull * V.T correctorsList = linalg.linSolve(KPatchFull + SPatchFull, bPatchFull.T) return correctorsList
def solveDampedFine_fem(world, aFine, bFine, f, uSol, tau, boundaryConditions, i): NWorldCoarse = world.NWorldCoarse NWorldFine = world.NWorldCoarse * world.NCoarseElement NpFine = np.prod(NWorldFine + 1) prevU = uSol[-1] if f is None: f = np.zeros(NpFine) boundaryMap = boundaryConditions == 0 fixedFine = util.boundarypIndexMap(NWorldFine, boundaryMap=boundaryMap) freeFine = np.setdiff1d(np.arange(NpFine), fixedFine) AFine = fem.assemblePatchMatrix(NWorldFine, world.MLocFine, aFine) BFine = fem.assemblePatchMatrix(NWorldFine, world.ALocFine, bFine) MFine = fem.assemblePatchMatrix(NWorldFine, world.MLocFine) bFine = MFine * f AFineFree = AFine[freeFine][:, freeFine] BFineFree = BFine[freeFine][:, freeFine] MFineFree = MFine[freeFine][:, freeFine] bFineFree = bFine[freeFine] A = (1. / tau**2) * MFineFree + (1. / tau) * AFineFree + BFineFree if i == 0: b = bFineFree + (1. / tau) * AFineFree * prevU[freeFine] + ( 1. / tau) * MFineFree * ((2. / tau) * prevU[freeFine]) else: b = bFineFree + (1. / tau) * AFineFree * prevU[freeFine] + ( 1. / tau) * MFineFree * ((2. / tau) * prevU[freeFine] - (1. / tau) * uSol[i - 1][freeFine]) uFineFree = linalg.linSolve(A, b) uFineFull = np.zeros(NpFine) uFineFull[freeFine] = uFineFree uFineFull = uFineFull return uFineFull
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 * fs_solutions[i] RmsFree = RmsFull[free][:, free] RmsFreeList.append(RmsFree) # add sum to linear system if i is not 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.append(ms_basis * VFull) # evaluate w^n w = 0 if i is not 0: for j in range(0, i + 1): w += fs_solutions[j] * V[n - j] WFine.append(w) '''
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]
# linear system A = (1. / tau) * SmsFree + KmsFree b = LmsFree + (1. / tau) * SmsFree * V[n][free] # store ms matrix R^{ms',h}_{H,i,k} RmsFull = ms_basis.T * S * fs_solutions[i] RmsFree = RmsFull[free][:, free] RmsFreeList.append(RmsFree) # add sum to linear system if i is not 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.append(ms_basis * VFull) # evaluate w^n w = 0 if i is not 0: for j in range(0, i + 1): w += fs_solutions[j] * V[n - j] WFine.append(w) ''' Compute standard LOD solution