def test_assemblePatchMatrix2d(self): NPatch = np.array([2, 2]) ALoc = np.ones((4, 4)) AComputed = fem.assemblePatchMatrix(NPatch, ALoc) ACorrect = np.array([[1, 1, 0, 1, 1, 0, 0, 0, 0], [1, 2, 1, 1, 2, 1, 0, 0, 0], [0, 1, 1, 0, 1, 1, 0, 0, 0], [1, 1, 0, 2, 2, 0, 1, 1, 0], [1, 2, 1, 2, 4, 2, 1, 2, 1], [0, 1, 1, 0, 2, 2, 0, 1, 1], [0, 0, 0, 1, 1, 0, 1, 1, 0], [0, 0, 0, 1, 2, 1, 1, 2, 1], [0, 0, 0, 0, 1, 1, 0, 1, 1]]) self.assertTrue(np.allclose(AComputed.todense(), ACorrect)) NPatch = np.array([2, 2]) ALoc = np.ones((4, 4)) aPatch = np.array([1, 2, 3, 4]) AComputed = fem.assemblePatchMatrix(NPatch, ALoc, aPatch) ACorrect = np.array([[1, 1, 0, 1, 1, 0, 0, 0, 0], [1, 3, 2, 1, 3, 2, 0, 0, 0], [0, 2, 2, 0, 2, 2, 0, 0, 0], [1, 1, 0, 4, 4, 0, 3, 3, 0], [1, 3, 2, 4, 10, 6, 3, 7, 4], [0, 2, 2, 0, 6, 6, 0, 4, 4], [0, 0, 0, 3, 3, 0, 3, 3, 0], [0, 0, 0, 3, 7, 4, 3, 7, 4], [0, 0, 0, 0, 4, 4, 0, 4, 4]]) self.assertTrue(np.allclose(AComputed.todense(), ACorrect))
def compute_element_corrector(self, b_patch, a_patch, IPatch, ARhsList): '''Compute the fine correctors over the patch. Compute the correctors a(Q_T \lambda_x, z)_{U_K(T)} + \tau b(Q_T \lambda_x, z)_{U_K(T)} = a(\lambda_x, z)_T + \tau b(\lambda_x, z)_T ''' numRhs = len(ARhsList) world = self.world NCoarseElement = world.NCoarseElement NPatchCoarse = self.NPatchCoarse NPatchFine = NPatchCoarse * NCoarseElement NtFine = np.prod(NPatchFine) NpFine = np.prod(NPatchFine + 1) b_patch = b_patch.aFine a_patch = a_patch.aFine assert (np.size(a_patch) == NtFine) iElementPatchCoarse = self.iElementPatchCoarse elementFinetIndexMap = util.extractElementFine(NPatchCoarse, NCoarseElement, iElementPatchCoarse, extractElements=True) elementFinepIndexMap = util.extractElementFine(NPatchCoarse, NCoarseElement, iElementPatchCoarse, extractElements=False) SElementFull = fem.assemblePatchMatrix(NCoarseElement, world.ALocFine, b_patch[elementFinetIndexMap]) KElementFull = fem.assemblePatchMatrix(NCoarseElement, world.ALocFine, a_patch[elementFinetIndexMap]) SPatchFull = fem.assemblePatchMatrix(NPatchFine, world.ALocFine, b_patch) KPatchFull = fem.assemblePatchMatrix(NPatchFine, world.ALocFine, a_patch) bPatchFullList = [] for rhsIndex in range(numRhs): bPatchFull = np.zeros(NpFine) bPatchFull[ elementFinepIndexMap] += SElementFull * ARhsList[rhsIndex] bPatchFull[ elementFinepIndexMap] += KElementFull * ARhsList[rhsIndex] bPatchFullList.append(bPatchFull) correctorsList = ritzProjectionToFinePatchWithGivenSaddleSolver( world, self.iPatchWorldCoarse, NPatchCoarse, SPatchFull + KPatchFull, bPatchFullList, IPatch, self.saddleSolver) return correctorsList
def test_stiffnessMatrixForIdentityMatrix(self): N = np.array([3, 4, 5], dtype='int64') aPatch = np.tile(np.eye(3), [3 * 4 * 5, 1, 1]) ALocTensor = fem.localStiffnessTensorMatrixCoefficient(N) A = fem.assemblePatchMatrix(N, ALocTensor, aPatch) ALoc = fem.localStiffnessMatrix(N) B = fem.assemblePatchMatrix(N, ALoc) self.assertTrue(np.allclose(A.data, B.data))
def compute_localized_node_correction(self, b_patch, a_patch, IPatch, ms_basis, prev_fs_sol, node_index): '''Compute the fine correctors over the node based patch. Compute the correctors, for all z \in V^f(U(\omega_{x,k})): a(\phi_x, z) + \tau b(\phi_x, z) = a(\lambda_x, z) + \tau b(\lambda_x, z) ''' world = self.world NCoarseElement = world.NCoarseElement NPatchCoarse = self.NPatchCoarse iPatchWorldCoarse = self.iPatchWorldCoarse NPatchFine = NPatchCoarse * NCoarseElement NtFine = np.prod(NPatchFine) NpFine = np.prod(NPatchFine + 1) iPatchWorldFine = iPatchWorldCoarse * NCoarseElement patchpIndexMap = util.lowerLeftpIndexMap(NPatchFine, world.NWorldFine) patchpStartIndex = util.convertpCoordinateToIndex(world.NWorldFine, iPatchWorldFine) patch_indices = patchpStartIndex + patchpIndexMap b_patch = b_patch.aFine a_patch = a_patch.aFine assert (np.size(b_patch) == NtFine) S_patch = fem.assemblePatchMatrix(NPatchFine, world.ALocFine, b_patch) K_patch = fem.assemblePatchMatrix(NPatchFine, world.ALocFine, a_patch) bPatchFull = np.zeros(NpFine) if prev_fs_sol is None: bPatchFull -= S_patch * ms_basis.toarray()[:, node_index][patch_indices] if prev_fs_sol is not None: bPatchFull += K_patch * prev_fs_sol.toarray()[:, node_index][patch_indices] fs_patch_solution = ritzProjectionToFinePatchWithGivenSaddleSolver(world, self.iPatchWorldCoarse, NPatchCoarse, S_patch + K_patch, [bPatchFull], IPatch, self.saddleSolver) fs_solution = np.zeros(world.NpFine) fs_solution[patch_indices] += fs_patch_solution[0] return fs_solution
def compute_node_correction(self, b_patch, a_patch, IPatch, prev_fs_sol, node_index=None): '''Compute the fine correctors over full domain Computes the correction: a(Q^h\lambda_x, z) + \tau b(Q^h\lambda_x, z) = a(\lambda_x, z) + \tau b(\lambda_x, z) if node_index is given, the calculations are done only for that node (used for rb testing) ''' 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) 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 = [] if node_index is None: for node_index in range(NpCoarse): bPatchFull = np.zeros(NpFine) bPatchFull += KPatchFull * prev_fs_sol.toarray()[:, node_index] bPatchFullList.append(bPatchFull) else: bPatchFull = np.zeros(NpFine) bPatchFull += KPatchFull * prev_fs_sol bPatchFullList.append(bPatchFull) correctorsList = ritzProjectionToFinePatchWithGivenSaddleSolver( world, self.iPatchWorldCoarse, NPatchCoarse, SPatchFull + KPatchFull, bPatchFullList, IPatch, self.saddleSolver) return correctorsList
def test_stiffnessMatrixForConstantFullA(self): N = np.array([3, 4, 5], dtype='int64') AConstant = np.array([[3.0, 0.2, 0.1], [0.2, 2.0, 0.3], [0.1, 0.3, 1.0]]) aPatch = np.tile(AConstant, [3 * 4 * 5, 1, 1]) ALocTensor = fem.localStiffnessTensorMatrixCoefficient(N) A = fem.assemblePatchMatrix(N, ALocTensor, aPatch) # Create the functions x1, x2 and x3 pc = util.pCoordinates(N) x1 = pc[:, 0] x2 = pc[:, 1] x3 = pc[:, 2] # Check diagonal elements self.assertTrue(np.isclose(np.dot(x1, A * x1), 3.0)) self.assertTrue(np.isclose(np.dot(x2, A * x2), 2.0)) self.assertTrue(np.isclose(np.dot(x3, A * x3), 1.0)) # Check off-diagonal elements self.assertTrue(np.isclose(np.dot(x1, A * x2), 0.2)) self.assertTrue(np.isclose(np.dot(x2, A * x1), 0.2)) self.assertTrue(np.isclose(np.dot(x1, A * x3), 0.1)) self.assertTrue(np.isclose(np.dot(x3, A * x1), 0.1)) self.assertTrue(np.isclose(np.dot(x2, A * x3), 0.3)) self.assertTrue(np.isclose(np.dot(x3, A * x2), 0.3))
def test_massMatrixProperties(self): # Mass bilinear form should satisfy 1'*M*1 = 1 NPatch = np.array([3, 4, 5]) MLoc = fem.localMassMatrix(NPatch) M = fem.assemblePatchMatrix(NPatch, MLoc) ones = np.ones(np.prod(NPatch + 1)) self.assertTrue(np.isclose(np.linalg.norm(np.dot(ones, M * ones)), 1))
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 test_trivial(self): NPatchCoarse = np.array([3,3]) NCoarseElement = np.array([2,2]) NPatchFine = NPatchCoarse*NCoarseElement Nt = np.prod(NPatchFine) Np = np.prod(NPatchFine+1) fixed = util.boundarypIndexMap(NPatchFine) world = World(NPatchCoarse, NCoarseElement) patch = Patch(world, 3, 0) aFlatPatchFine = np.ones(Nt) ALoc = fem.localStiffnessMatrix(NPatchFine) APatchFull = fem.assemblePatchMatrix(NPatchFine, ALoc, aFlatPatchFine) PPatch = fem.assembleProlongationMatrix(NPatchCoarse, NCoarseElement) IPatchNodal = interp.nodalPatchMatrix(patch) #IPatchuncL2 = interp.uncoupledL2ProjectionPatchMatrix(np.array([0, 0]), NPatchCoarse, NPatchCoarse, NCoarseElement) IPatchL2 = interp.L2ProjectionPatchMatrix(patch) for IPatch in [IPatchNodal, IPatchL2]: np.random.seed(0) bPatchFullList = [] self.assertTrue(not lod.ritzProjectionToFinePatch(patch, APatchFull, bPatchFullList, IPatch)) bPatchFullList = [np.zeros(Np)] projections = lod.ritzProjectionToFinePatch(patch, APatchFull, bPatchFullList, IPatch) self.assertEqual(len(projections), 1) self.assertTrue(np.allclose(projections[0], 0*projections[0])) bPatchFull = np.random.rand(Np) bPatchFullList = [bPatchFull] projections = lod.ritzProjectionToFinePatch(patch, APatchFull, bPatchFullList, IPatch) self.assertTrue(np.isclose(np.linalg.norm(IPatch*projections[0]), 0)) self.assertTrue(np.isclose(np.dot(projections[0], APatchFull*projections[0]), np.dot(projections[0], bPatchFullList[0]))) self.assertTrue(np.isclose(np.linalg.norm(projections[0][fixed]), 0)) bPatchFullList = [bPatchFull, -bPatchFull] projections = lod.ritzProjectionToFinePatch(patch, APatchFull, bPatchFullList, IPatch) self.assertTrue(np.allclose(projections[0], -projections[1])) bPatchFullList = [np.random.rand(Np), np.random.rand(Np)] projections = lod.ritzProjectionToFinePatch(patch, APatchFull, bPatchFullList, IPatch) self.assertTrue(np.isclose(np.dot(projections[1], APatchFull*projections[0]), np.dot(projections[1], bPatchFullList[0]))) bPatchFull = np.random.rand(Np) bPatchFullList = [bPatchFull] projectionCheckAgainst = lod.ritzProjectionToFinePatch(patch, APatchFull, bPatchFullList, IPatch)[0] for saddleSolver in [#lod.nullspaceOneLevelHierarchySolver(NPatchCoarse, NCoarseElement), lod.SchurComplementSolver()]: projection = lod.ritzProjectionToFinePatch(patch, APatchFull, bPatchFullList, IPatch, saddleSolver)[0] self.assertTrue(np.isclose(np.max(np.abs(projectionCheckAgainst-projection)), 0))
def test_stiffnessMatrixProperties(self): # Stiffness bilinear form should map constants to 0 NPatch = np.array([3, 4, 5]) ALoc = fem.localStiffnessMatrix(NPatch) aPatch = np.arange(np.prod(NPatch)) A = fem.assemblePatchMatrix(NPatch, ALoc, aPatch) constant = np.ones(np.prod(NPatch + 1)) self.assertTrue(np.isclose(np.linalg.norm(A * constant), 0))
def test_computeFullDomain(self): NWorldCoarse = np.array([2, 3, 4], dtype='int64') NWorldCoarse = np.array([1, 1, 1], dtype='int64') NCoarseElement = np.array([4, 2, 3], dtype='int64') NWorldFine = NWorldCoarse*NCoarseElement NpWorldFine = np.prod(NWorldFine+1) NpWorldCoarse = np.prod(NWorldCoarse+1) NtWorldFine = np.prod(NWorldCoarse*NCoarseElement) np.random.seed(0) world = World(NWorldCoarse, NCoarseElement) d = np.size(NWorldCoarse) IWorld = interp.nodalPatchMatrix(0*NWorldCoarse, NWorldCoarse, NWorldCoarse, NCoarseElement) aWorld = np.exp(np.random.rand(NtWorldFine)) coefficientWorld = coef.coefficientFine(NWorldCoarse, NCoarseElement, aWorld) k = np.max(NWorldCoarse) elementpIndexMap = util.lowerLeftpIndexMap(np.ones_like(NWorldCoarse), NWorldCoarse) elementpIndexMapFine = util.lowerLeftpIndexMap(NCoarseElement, NWorldFine) coarsepBasis = util.linearpIndexBasis(NWorldCoarse) finepBasis = util.linearpIndexBasis(NWorldFine) correctors = np.zeros((NpWorldFine, NpWorldCoarse)) basis = np.zeros((NpWorldFine, NpWorldCoarse)) for iElementWorldCoarse in it.product(*[np.arange(n, dtype='int64') for n in NWorldCoarse]): iElementWorldCoarse = np.array(iElementWorldCoarse) ec = lod.elementCorrector(world, k, iElementWorldCoarse) ec.computeCorrectors(coefficientWorld, IWorld) worldpIndices = np.dot(coarsepBasis, iElementWorldCoarse) + elementpIndexMap correctors[:,worldpIndices] += np.column_stack(ec.fsi.correctorsList) worldpFineIndices = np.dot(finepBasis, iElementWorldCoarse*NCoarseElement) + elementpIndexMapFine basis[np.ix_(worldpFineIndices, worldpIndices)] = world.localBasis AGlob = fem.assemblePatchMatrix(NWorldFine, world.ALocFine, aWorld) alpha = np.random.rand(NpWorldCoarse) vH = np.dot(basis, alpha) QvH = np.dot(correctors, alpha) # Check norm inequality self.assertTrue(np.dot(QvH.T, AGlob*QvH) <= np.dot(vH.T, AGlob*vH)) # Check that correctors are really fine functions self.assertTrue(np.isclose(np.linalg.norm(IWorld*correctors, ord=np.inf), 0)) v = np.random.rand(NpWorldFine, NpWorldCoarse) v[util.boundarypIndexMap(NWorldFine)] = 0 # The chosen interpolation operator doesn't ruin the boundary conditions. vf = v-np.dot(basis, IWorld*v) vf = vf/np.sqrt(np.sum(vf*(AGlob*vf), axis=0)) # Check orthogonality self.assertTrue(np.isclose(np.linalg.norm(np.dot(vf.T, AGlob*(correctors - basis)), ord=np.inf), 0))
def test_testCsi(self): NWorldCoarse = np.array([4, 5, 6]) NCoarseElement = np.array([5, 2, 3]) world = World(NWorldCoarse, NCoarseElement) d = np.size(NWorldCoarse) k = 1 iElementWorldCoarse = np.array([2, 1, 2]) ec = lod.elementCorrector(world, k, iElementWorldCoarse) IPatch = interp.L2ProjectionPatchMatrix(ec.iPatchWorldCoarse, ec.NPatchCoarse, NWorldCoarse, NCoarseElement) NtPatch = np.prod(ec.NPatchCoarse*NCoarseElement) np.random.seed(1) aPatch = np.random.rand(NtPatch) coefficientPatch = coef.coefficientFine(ec.NPatchCoarse, NCoarseElement, aPatch) ec.computeCorrectors(coefficientPatch, IPatch) ec.computeCoarseQuantities() TFinetIndexMap = util.extractElementFine(ec.NPatchCoarse, NCoarseElement, ec.iElementPatchCoarse, extractElements=True) TFinepIndexMap = util.extractElementFine(ec.NPatchCoarse, NCoarseElement, ec.iElementPatchCoarse, extractElements=False) TCoarsepIndexMap = util.extractElementFine(ec.NPatchCoarse, np.ones_like(NCoarseElement), ec.iElementPatchCoarse, extractElements=False) APatchFine = fem.assemblePatchMatrix(ec.NPatchCoarse*NCoarseElement, world.ALocFine, aPatch) AElementFine = fem.assemblePatchMatrix(NCoarseElement, world.ALocFine, aPatch[TFinetIndexMap]) basisPatch = fem.assembleProlongationMatrix(ec.NPatchCoarse, NCoarseElement) correctorsPatch = np.column_stack(ec.fsi.correctorsList) localBasis = world.localBasis KmsijShouldBe = -basisPatch.T*(APatchFine*(correctorsPatch)) KmsijShouldBe[TCoarsepIndexMap,:] += np.dot(localBasis.T, AElementFine*localBasis) self.assertTrue(np.isclose(np.max(np.abs(ec.csi.Kmsij-KmsijShouldBe)), 0))
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 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 test_testCsi_Kmsij(self): NWorldCoarse = np.array([4, 5, 6]) NCoarseElement = np.array([5, 2, 3]) world = World(NWorldCoarse, NCoarseElement) d = np.size(NWorldCoarse) k = 1 iElementWorldCoarse = np.array([2, 1, 2]) TInd = util.convertpCoordIndexToLinearIndex(NWorldCoarse, iElementWorldCoarse) patch = Patch(world, k, TInd) IPatch = interp.L2ProjectionPatchMatrix(patch) NtPatch = patch.NtFine np.random.seed(1) aPatch = np.random.rand(NtPatch) basisCorrectorsList = lod.computeBasisCorrectors(patch, IPatch, aPatch) csi = lod.computeBasisCoarseQuantities(patch, basisCorrectorsList, aPatch) TFinetIndexMap = util.extractElementFine(patch.NPatchCoarse, NCoarseElement, patch.iElementPatchCoarse, extractElements=True) TFinepIndexMap = util.extractElementFine(patch.NPatchCoarse, NCoarseElement, patch.iElementPatchCoarse, extractElements=False) TCoarsepIndexMap = util.extractElementFine(patch.NPatchCoarse, np.ones_like(NCoarseElement), patch.iElementPatchCoarse, extractElements=False) APatchFine = fem.assemblePatchMatrix(patch.NPatchFine, world.ALocFine, aPatch) AElementFine = fem.assemblePatchMatrix(NCoarseElement, world.ALocFine, aPatch[TFinetIndexMap]) basisPatch = fem.assembleProlongationMatrix(patch.NPatchCoarse, NCoarseElement) correctorsPatch = np.column_stack(basisCorrectorsList) localBasis = world.localBasis KmsijShouldBe = -basisPatch.T*(APatchFine*(correctorsPatch)) KmsijShouldBe[TCoarsepIndexMap,:] += np.dot(localBasis.T, AElementFine*localBasis) self.assertTrue(np.isclose(np.max(np.abs(csi.Kmsij-KmsijShouldBe)), 0))
def compute_localized_basis_node(self, b_patch, a_patch, IPatch, basis, node_index): ''' Description ''' world = self.world NCoarseElement = world.NCoarseElement NPatchCoarse = self.NPatchCoarse iPatchWorldCoarse = self.iPatchWorldCoarse NPatchFine = NPatchCoarse * NCoarseElement NtFine = np.prod(NPatchFine) NpFine = np.prod(NPatchFine + 1) 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) S_patch = fem.assemblePatchMatrix(NPatchFine, world.ALocFine, b_patch) K_patch = fem.assemblePatchMatrix(NPatchFine, world.ALocFine, a_patch) bPatchFull = np.zeros(NpFine) bPatchFull += K_patch * basis.toarray()[:, node_index][patch_indices] bPatchFull += S_patch * basis.toarray()[:, node_index][patch_indices] ms_basis_patch_solution = ritzProjectionToFinePatchWithGivenSaddleSolver( world, self.iPatchWorldCoarse, NPatchCoarse, S_patch + K_patch, [bPatchFull], IPatch, self.saddleSolver) ms_basis_solution = np.zeros(world.NpFine) ms_basis_solution[patch_indices] += ms_basis_patch_solution[0] return ms_basis_solution
def solvePeriodic(world, KmsFull, rhs, faverage, boundaryConditions=None): ''' solves a pglod linear system with periodic boundary conditions, adapted from gridlod.pglod.solves''' NWorldCoarse = world.NWorldCoarse NpCoarse = np.prod(NWorldCoarse + 1) d = np.size(NWorldCoarse) MCoarse = fem.assemblePatchMatrix(world.NWorldCoarse, world.MLocCoarse) averageVector = MCoarse * np.ones(NpCoarse) bFull = np.copy(rhs) if d == 1: free = np.arange(1, NpCoarse-1) elif d == 2: fixed = np.concatenate((np.arange(NWorldCoarse[1]*(NWorldCoarse[0]+1), NpCoarse), np.arange(NWorldCoarse[0], NpCoarse-1, NWorldCoarse[0]+1))) free = np.setdiff1d(np.arange(NpCoarse), fixed) bFull[np.arange(0, NWorldCoarse[1] * (NWorldCoarse[0] + 1)+1, NWorldCoarse[0] + 1)] \ += bFull[np.arange(NWorldCoarse[0], NpCoarse, NWorldCoarse[0]+1)] bFull[np.arange(NWorldCoarse[0] + 1)] += bFull[np.arange(NWorldCoarse[1]*(NWorldCoarse[0]+1), NpCoarse)] averageVector[np.arange(0, NWorldCoarse[1] * (NWorldCoarse[0] + 1)+1, NWorldCoarse[0] + 1)] \ += averageVector[np.arange(NWorldCoarse[0], NpCoarse, NWorldCoarse[0]+1)] averageVector[np.arange(NWorldCoarse[0] + 1)] += averageVector[np.arange(NWorldCoarse[1]*(NWorldCoarse[0]+1), NpCoarse)] else: NotImplementedError('higher dimensions not yet implemented') KmsFree = KmsFull[free][:, free] constraint = averageVector[free].reshape((1,KmsFree.shape[0])) K = sparse.bmat([[KmsFree, constraint.T], [constraint, None]], format='csc') bFree = bFull[free] - faverage * averageVector[free] #right-hand side with non-zero average potentially not working correctly yet b = np.zeros(K.shape[0]) b[:np.size(bFree)] = bFree x = sparse.linalg.spsolve(K,b) uFree = x[:np.size(bFree)] uFull = np.zeros(NpCoarse) uFull[free] = uFree if d == 1: uFull[NpCoarse-1] = uFull[0] #not relevant in 1d elif d == 2: uFull[np.arange(NWorldCoarse[0], NpCoarse-1, NWorldCoarse[0]+1)] \ += uFull[np.arange(0, NWorldCoarse[1]*(NWorldCoarse[0]+1),NWorldCoarse[0]+1)] uFull[np.arange(NWorldCoarse[1]*(NWorldCoarse[0]+1), NpCoarse)] += uFull[np.arange(NWorldCoarse[0]+1)] else: NotImplementedError('higher dimensiona not yet implemented') return uFull, uFree
def addtoA(A, kk): ii = kk[0] jj = kk[1] bij = (mu[ii] * np.sqrt(a) * (1 - aRefList[ii] / a)) * (mu[jj] * np.sqrt(a) * (1 - aRefList[jj] / a)) PatchNorm = fem.assemblePatchMatrix(NPatchFine, ALocFine, bij) Q1 = np.column_stack(correctorsList[ii]) Q2 = np.column_stack(correctorsList[jj]) A += np.dot(Q1.T, PatchNorm * Q2) if aPatchNew is not None: bii = mu[ii] * np.sqrt(a) * (1 - aRefList[ii] / a) bjj = mu[jj] * np.sqrt(a) * (1 - aRefList[jj] / a) bTii = bT * bii[TFinetStartIndex + TFinetIndexMap] bTjj = bT * bjj[TFinetStartIndex + TFinetIndexMap] TNormPQ = fem.assemblePatchMatrix(NCoarseElement, ALocFine, bTjj) TNormQP = fem.assemblePatchMatrix(NCoarseElement, ALocFine, bTii) QT1 = Q1[TFinepStartIndex + TFinepIndexMap, :] QT2 = Q2[TFinepStartIndex + TFinepIndexMap, :] A -= np.dot(P.T, TNormPQ * QT2) A -= np.dot(QT1.T, TNormQP * P)
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
def test_stiffessMatrix(self): # Compare stiffness matrix from PG object with the one # computed from correctors and fine stiffness matrix NWorldFine = np.array([10, 10]) NpFine = np.prod(NWorldFine + 1) NtFine = np.prod(NWorldFine) NWorldCoarse = np.array([2, 2]) NCoarseElement = NWorldFine / NWorldCoarse NtCoarse = np.prod(NWorldCoarse) NpCoarse = np.prod(NWorldCoarse + 1) world = World(NWorldCoarse, NCoarseElement) np.random.seed(0) aBase = np.random.rand(NtFine) aCoef = coef.coefficientFine(NWorldCoarse, NCoarseElement, aBase) IPatchGenerator = lambda i, N: interp.L2ProjectionPatchMatrix( i, N, NWorldCoarse, NCoarseElement) IWorld = IPatchGenerator(0 * NWorldCoarse, NWorldCoarse) k = 2 printLevel = 0 pglod = pg.PetrovGalerkinLOD(world, k, IPatchGenerator, 0, printLevel) pglod.updateCorrectors(aCoef, clearFineQuantities=False) KmsFull = pglod.assembleMsStiffnessMatrix() KFull = pglod.assembleStiffnessMatrix() basis = fem.assembleProlongationMatrix(NWorldCoarse, NCoarseElement) basisCorrectors = pglod.assembleBasisCorrectors() self.assertTrue( np.isclose(np.linalg.norm(IWorld * basisCorrectors.todense()), 0)) modifiedBasis = basis - basisCorrectors AFine = fem.assemblePatchMatrix(NWorldFine, world.ALocFine, aBase) KmsRef = np.dot(basis.T, AFine * modifiedBasis) KRef = np.dot(basis.T, AFine * basis) self.assertTrue( np.isclose(np.linalg.norm(KFull.todense() - KRef.todense()), 0)) self.assertTrue( np.isclose(np.linalg.norm(KmsFull.todense() - KmsRef.todense()), 0))
def test_stiffnessMatrixForVaryingDiagonalA(self): N = np.array([3, 4, 5], dtype='int64') AConstant1 = np.array([[1.0, 0, 0], [0, 2.0, 0], [0, 0, 1.0]]) AConstant2 = np.array([[1.0, 0, 0], [0, 7.0, 0], [0, 0, 1.0]]) aPatchCube = np.tile(AConstant1, [3, 4, 5, 1, 1]) aPatchCube[:, :2, :, :, :] = AConstant2 aPatch = np.reshape(aPatchCube, [3 * 4 * 5, 3, 3]) ALocTensor = fem.localStiffnessTensorMatrixCoefficient(N) A = fem.assemblePatchMatrix(N, ALocTensor, aPatch) # Create the functions x1, x2 and x3 pc = util.pCoordinates(N) x1 = pc[:, 0] x2 = pc[:, 1] x3 = pc[:, 2] self.assertTrue(np.isclose(np.dot(x1, A * x1), 1.0)) self.assertTrue(np.isclose(np.dot(x2, A * x2), 0.5 * (2. + 7.))) self.assertTrue(np.isclose(np.dot(x3, A * x3), 1.0))
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 test_ritzProjectionToFinePatchBoundaryConditions(self): NPatchCoarse = np.array([4, 4]) NCoarseElement = np.array([10, 10]) world = World(NPatchCoarse, NCoarseElement) patch = Patch(world, 4, 0) NPatchFine = NPatchCoarse*NCoarseElement NpFine = np.prod(NPatchFine + 1) APatchFull = fem.assemblePatchMatrix(NPatchCoarse*NCoarseElement, world.ALocFine) bPatchFullList = [np.ones(NpFine)] fixed = util.boundarypIndexMap(NPatchFine) for IPatch in [interp.L2ProjectionPatchMatrix(patch), interp.nodalPatchMatrix(patch)]: schurComplementSolver = lod.SchurComplementSolver() schurComplementSolution = lod.ritzProjectionToFinePatch(patch, APatchFull, bPatchFullList, IPatch, schurComplementSolver)[0] self.assertTrue(np.isclose(np.max(np.abs(schurComplementSolution[fixed])), 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
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
V.append(Uo) # fine v^(-1) and v^0 VFine = [ms_basis * Uo] VFine.append(ms_basis * Uo) # reference solution UFine = [ms_basis * Uo] 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)
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