# safe NworldCoarse with open("%s/NWorldCoarse.txt" % ROOT, 'w') as csvfile: writer = csv.writer(csvfile) for val in NWorldCoarse: writer.writerow([val]) # ABase with open("%s/OriginalCoeff.txt" % ROOT, 'w') as csvfile: writer = csv.writer(csvfile) for val in ABase: writer.writerow([val]) # fine-fem f_fine = np.ones(NpFine) uFineFem, AFine, MFine = femsolver.solveFine(world, ABase, f_fine, None, boundaryConditions) # fine solution with open("%s/finescale.txt" % ROOT, 'w') as csvfile: writer = csv.writer(csvfile) for val in uFineFem: writer.writerow([val]) plt.figure("Original") drawCoefficient(NWorldFine, ABase, greys=True) plt.title("Original coefficient") # random seed random.seed(20) # decision
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
plt.figure("Coefficient") drawCoefficient_origin(NFine, aFine_ref) plt.figure("Perturbed coefficient") drawCoefficient_origin(NFine, aFine_trans) plt.figure('Right hand side') draw_f(NFine+1, f_ref) plt.show() ''' Compute FEM ''' uFineFull_trans, AFine_trans, _ = femsolver.solveFine(world, aFine_trans, f_ref, None, boundaryConditions) ''' Set the coefficient that we want to approximate and the tolerance ''' a_Fine_to_be_approximated = aFine_trans ''' Compute PGLOD ''' def real_computeKmsij(TInd): print('.', end='', flush=True) patch = Patch(world, k, TInd)
drawCoefficient_origin(NFine, aFine_pert) plt.figure('transformed') drawCoefficient_origin(NFine, aFine_trans) plt.figure('Right hand side') draw_f(NFine+1, f_ref) plt.show() ''' Check whether domain mapping method works sufficiently good ''' uFineFull_pert, AFine_pert, _ = femsolver.solveFine(world, aFine_pert, f_pert, None, boundaryConditions) uFineFull_trans, AFine_trans, _ = femsolver.solveFine(world, aFine_trans, f_trans, None, boundaryConditions) u_FineFull_trans_pert = bending_perturbation.evaluateSolution(uFineFull_trans) energy_norm = np.sqrt(np.dot(uFineFull_pert, AFine_pert * uFineFull_pert)) energy_error = np.sqrt(np.dot((u_FineFull_trans_pert - uFineFull_pert), AFine_pert * (u_FineFull_trans_pert - uFineFull_pert))) print("Domain Mapping with FEM: Energy norm {}, error {}, rel. error {}".format(energy_norm, energy_error, energy_error / energy_norm)) ''' Set the coefficient that we want to approximate and the tolerance ''' a_Fine_to_be_approximated = aFine_trans
BoundarySpace=True) a_fine = CoefClass.BuildCoefficient().flatten() plt.figure("Coefficient") drawCoefficient_origin(NFine, a_fine) f = np.ones(np.prod(NFine + 1)) NWorldCoarse = np.array([N, N]) boundaryConditions = np.array([[0, 0], [0, 0]]) NCoarseElement = NFine // NWorldCoarse world = World(NWorldCoarse, NCoarseElement, boundaryConditions) uFineFull, AFine, _ = femsolver.solveFine(world, a_fine, f, None, boundaryConditions) k = 2 def computeKmsij(TInd): patch = Patch(world, k, TInd) IPatch = lambda: interp.L2ProjectionPatchMatrix(patch, boundaryConditions) aPatch = lambda: coef.localizeCoefficient(patch, a_fine) 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)
def Monte_Carlo_simulation(): print('Computing Monte Carlo step') global aFine_ref global aFine_trans global aFine_pert global k global KmsijT global correctorsListT aFine_ref = aFine_ref_shaped.flatten() psi, cq1 = create_psi_function() # plt.figure('domain mapping') # plt.plot(np.arange(0, fine + 1), cq1[0, :], label='$id(x) - \psi(x)$') # plt.plot(np.arange(0, fine), ref_array * 0.01) # plt.title('Domain mapping') # plt.legend() xpFine_pert = psi.evaluate(xpFine) xpFine_ref = psi.inverse_evaluate(xpFine) xtFine_pert = psi.evaluate(xtFine) xtFine_ref = psi.inverse_evaluate(xtFine) aFine_pert = func.evaluateDQ0(NFine, aFine_ref, xtFine_ref) aBack_ref = func.evaluateDQ0(NFine, aFine_pert, xtFine_pert) print('Psi is invertible if this is zero: {}'.format( np.linalg.norm(aBack_ref - aFine_ref))) every_psi_was_valid.append(np.linalg.norm(aBack_ref - aFine_ref)) #aFine_trans is the transformed perturbed reference coefficient aFine_trans = np.einsum('tji, t, tkj, t -> tik', psi.Jinv(xtFine), aFine_ref, psi.Jinv(xtFine), psi.detJ(xtFine)) f_pert = np.ones(np.prod(NFine + 1)) f_ref = func.evaluateCQ1(NFine, f_pert, xpFine_pert) f_trans = np.einsum('t, t -> t', f_ref, psi.detJ(xpFine)) uFineFull_pert, AFine_pert, MFine = femsolver.solveFine( world, aFine_pert, f_pert, None, boundaryConditions) uFineFull_trans, AFine_trans, _ = femsolver.solveFine( world, aFine_trans, f_trans, None, boundaryConditions) uFineFull_trans_pert = func.evaluateCQ1(NFine, uFineFull_trans, xpFine_ref) energy_norm = np.sqrt(np.dot(uFineFull_pert, AFine_pert * uFineFull_pert)) energy_error = np.sqrt( np.dot((uFineFull_trans_pert - uFineFull_pert), AFine_pert * (uFineFull_trans_pert - uFineFull_pert))) print("Energy norm {}, error {}, rel. error {}".format( energy_norm, energy_error, energy_error / energy_norm)) Aeye = np.tile(np.eye(2), [np.prod(NFine), 1, 1]) aFine_ref = np.einsum('tji, t-> tji', Aeye, aFine_ref) print('compute domain mapping error indicators') epsFine, epsCoarse = zip(*map(computeIndicators, range(world.NtCoarse))) print('apply tolerance') Elements_to_be_updated = [] TOL = 0.1 for i in range(world.NtCoarse): if epsFine[i] >= TOL: Elements_to_be_updated.append(i) print('.... to be updated for domain mapping: {}%'.format( np.size(Elements_to_be_updated) / np.size(epsFine) * 100)) print('update correctors') if np.size(Elements_to_be_updated) == 0: correctorsListTNew, KmsijTNew = correctorsListT, KmsijT else: patchT_irrelevant, correctorsListTNew, KmsijTNew, csiTNew = zip( *map(UpdateCorrectors, Elements_to_be_updated)) KmsijT_list = list(KmsijT) correctorsListT_list = list(correctorsListT) i = 0 for T in Elements_to_be_updated: KmsijT_list[T] = KmsijTNew[i] correctorsListT_list[T] = correctorsListTNew[i] i += 1 KmsijT = tuple(KmsijT_list) correctorsListT = tuple(correctorsListT_list) print('solve the system') KFull = pglod.assembleMsStiffnessMatrix(world, patchT, KmsijT) MFull = fem.assemblePatchMatrix(NFine, world.MLocFine) basis = fem.assembleProlongationMatrix(NWorldCoarse, NCoarseElement) basisCorrectors = pglod.assembleBasisCorrectors(world, patchT, correctorsListT) modifiedBasis = basis - basisCorrectors bFull = MFull * f_trans bFull = basis.T * bFull uFull, _ = pglod.solve(world, KFull, bFull, boundaryConditions) uLodFine = modifiedBasis * uFull uLodFine_METHOD = uLodFine newErrorFine = np.sqrt( np.dot(uLodFine - uFineFull_trans, AFine_trans * (uLodFine - uFineFull_trans))) print('Method error: {}'.format(newErrorFine)) print('update all correctors') patchT_irrelevant, correctorsListT, KmsijT, csiTNew = zip( *map(UpdateCorrectors, range(world.NtCoarse))) print('solve the system') KFull = pglod.assembleMsStiffnessMatrix(world, patchT, KmsijT) MFull = fem.assemblePatchMatrix(NFine, world.MLocFine) basis = fem.assembleProlongationMatrix(NWorldCoarse, NCoarseElement) basisCorrectors = pglod.assembleBasisCorrectors(world, patchT, correctorsListT) modifiedBasis = basis - basisCorrectors bFull = MFull * f_trans bFull = basis.T * bFull uFull, _ = pglod.solve(world, KFull, bFull, boundaryConditions) uLodFine = modifiedBasis * uFull newErrorFine = np.sqrt( np.dot(uLodFine - uFineFull_trans, AFine_trans * (uLodFine - uFineFull_trans))) print('Exact LOD error: {}'.format(newErrorFine)) return uLodFine_METHOD, uLodFine, uFineFull_pert, MFine
def test_00coarseFlux(self): NWorldFine = np.array([20, 20]) NpFine = np.prod(NWorldFine + 1) NtFine = np.prod(NWorldFine) NWorldCoarse = np.array([4, 4]) NCoarseElement = NWorldFine / NWorldCoarse NtCoarse = np.prod(NWorldCoarse) NpCoarse = np.prod(NWorldCoarse + 1) boundaryConditions = np.array([[0, 0], [1, 1]]) world = World(NWorldCoarse, NCoarseElement, boundaryConditions) np.random.seed(0) aBaseSquare = np.exp(5 * np.random.random_sample(NWorldFine[1])) aBaseCube = np.tile(aBaseSquare[..., np.newaxis], [NWorldFine[0], 1]) aBaseCube = aBaseCube[..., np.newaxis] aBase = aBaseCube.flatten() IPatchGenerator = lambda i, N: interp.L2ProjectionPatchMatrix( i, N, NWorldCoarse, NCoarseElement, boundaryConditions) aCoef = coef.coefficientFine(NWorldCoarse, NCoarseElement, aBase) k = 4 printLevel = 0 pglod = pg.PetrovGalerkinLOD(world, k, IPatchGenerator, 0, printLevel) pglod.updateCorrectors(aCoef) KmsFull = pglod.assembleMsStiffnessMatrix() coords = util.pCoordinates(NWorldCoarse) xC = coords[:, 0] g = 1 - xC bFull = -KmsFull * g boundaryMap = boundaryConditions == 0 fixed = util.boundarypIndexMap(NWorldCoarse, boundaryMap) free = np.setdiff1d(np.arange(0, NpCoarse), fixed) KmsFree = KmsFull[free][:, free] bFree = bFull[free] xFree = sparse.linalg.spsolve(KmsFree, bFree) xFull = np.zeros(NpCoarse) xFull[free] = xFree uFull = xFull + g lodFluxTF = pglod.computeFaceFluxTF(uFull) ## Compute fine solution coords = util.pCoordinates(NWorldFine) xF = coords[:, 0] gFine = 1 - xF uFineFull, AFine, _ = femsolver.solveFine(world, aBase, None, -gFine, boundaryConditions) uFineFull = uFineFull + gFine fineFluxTF = transport.computeHarmonicMeanFaceFlux( NWorldCoarse, NWorldCoarse, NCoarseElement, aBase, uFineFull) self.assertTrue(np.allclose(lodFluxTF, fineFluxTF, rtol=1e-7))
transformed_problem = [] non_transformed_problem = [] energy_error = [] x = [] for N in NList: NWorldCoarse = np.array([N]) boundaryConditions = np.array([[0, 0]]) NCoarseElement = NFine // NWorldCoarse world = World(NWorldCoarse, NCoarseElement, boundaryConditions) # grid nodes xpCoarse = util.pCoordinates(NFine).flatten() x.append(xpCoarse) NpCoarse = np.prod(NWorldCoarse + 1) uFineFull, AFine, nothing = femsolver.solveFine(world, aPert, f, None, boundaryConditions) uFineFullJAJ, jAjFine, nothing = femsolver.solveFine(world, jAj, f_pert, None, boundaryConditions) uFineFull_transformed = np.copy(uFineFullJAJ) k = 0 uFineFull_transformed = psi.inverse_transformation(uFineFullJAJ, xpCoarse) energy_error.append(np.sqrt(np.dot(uFineFull - uFineFull_transformed, AFine * (uFineFull - uFineFull_transformed)))) exact_problem.append(uFineFull) non_transformed_problem.append(uFineFullJAJ) transformed_problem.append(uFineFull_transformed) # here, we compare the solutions. # todo: we need a better error comparison !! This is not looking good at all.
def test_3d(self): return NWorldFine = np.array([60, 220, 50]) NpFine = np.prod(NWorldFine + 1) NtFine = np.prod(NWorldFine) NWorldCoarse = np.array([6, 22, 5]) NCoarseElement = NWorldFine / NWorldCoarse NtCoarse = np.prod(NWorldCoarse) NpCoarse = np.prod(NWorldCoarse + 1) boundaryConditions = np.array([[1, 1], [0, 0], [1, 1]]) world = World(NWorldCoarse, NCoarseElement, boundaryConditions) aBase = np.loadtxt( os.path.dirname(os.path.realpath(__file__)) + '/data/upperness_x.txt') #aBase = aBase[::8] print 'a' coords = util.pCoordinates(NWorldFine) gFine = 1 - coords[:, 1] uFineFull, AFine, _ = femsolver.solveFine(world, aBase, None, -gFine, boundaryConditions) print 'b' rCoarse = np.ones(NtCoarse) self.assertTrue(np.size(aBase) == NtFine) if True: IPatchGenerator = lambda i, N: interp.L2ProjectionPatchMatrix( i, N, NWorldCoarse, NCoarseElement, boundaryConditions) aCoef = coef.coefficientCoarseFactor(NWorldCoarse, NCoarseElement, aBase, rCoarse) k = 2 printLevel = 1 pglod = pg.PetrovGalerkinLOD(world, k, IPatchGenerator, 1e-1, printLevel) pglod.updateCorrectors(aCoef, clearFineQuantities=True) KmsFull = pglod.assembleMsStiffnessMatrix() coords = util.pCoordinates(NWorldCoarse) g = 1 - coords[:, 1] bFull = -KmsFull * g boundaryMap = boundaryConditions == 0 fixed = util.boundarypIndexMap(NWorldCoarse, boundaryMap) free = np.setdiff1d(np.arange(0, NpCoarse), fixed) KmsFree = KmsFull[free][:, free] bFree = bFull[free] xFree = sparse.linalg.spsolve(KmsFree, bFree) uCoarse = np.zeros(NpCoarse) uCoarse[free] = xFree uCoarse += g uCube = np.reshape(uCoarse, (NWorldCoarse + 1)[::-1]) uCube = np.ascontiguousarray(np.transpose(uCube, axes=[2, 1, 0])) imageToVTK("./image", pointData={"u": uCube}) if False: coord = util.pCoordinates(NWorldCoarse) uCoarse = coord[:, 1].flatten() uCube = np.reshape(uCoarse, (NWorldCoarse + 1)[::-1]) uCube = np.ascontiguousarray(np.transpose(uCube, axes=[2, 1, 0])) imageToVTK("./image", pointData={"u": uCube})
def test_2d_exactSolution(self): NWorldFine = np.array([30, 40]) NpFine = np.prod(NWorldFine + 1) NtFine = np.prod(NWorldFine) NWorldCoarse = np.array([3, 4]) NCoarseElement = NWorldFine / NWorldCoarse NtCoarse = np.prod(NWorldCoarse) NpCoarse = np.prod(NWorldCoarse + 1) boundaryConditions = np.array([[0, 0], [1, 1]]) world = World(NWorldCoarse, NCoarseElement, boundaryConditions) np.random.seed(0) aBaseSquare = np.exp(5 * np.random.random_sample(NWorldFine[0])) aBaseCube = np.tile(aBaseSquare, [NWorldFine[1], 1]) aBaseCube = aBaseCube[..., np.newaxis] aBase = aBaseCube.flatten() IPatchGenerator = lambda i, N: interp.L2ProjectionPatchMatrix( i, N, NWorldCoarse, NCoarseElement, boundaryConditions) rCoarse = np.ones(NtCoarse) aCoef = coef.coefficientCoarseFactor(NWorldCoarse, NCoarseElement, aBase, rCoarse) k = 4 printLevel = 0 epsilonTol = 0.05 pglod = pg.PetrovGalerkinLOD(world, k, IPatchGenerator, epsilonTol, printLevel) pglod.updateCorrectors(aCoef, clearFineQuantities=False) boundaryMap = boundaryConditions == 0 fixed = util.boundarypIndexMap(NWorldCoarse, boundaryMap) free = np.setdiff1d(np.arange(0, NpCoarse), fixed) coords = util.pCoordinates(NWorldCoarse) xC = coords[:, 0] yC = coords[:, 1] g = 1 - xC firstIteration = True # First case is to not modify. Error should be 0 # The other cases modify one, a few or half of the coarse elements to different degrees. rCoarseModPairs = [([], []), ([0], [2.]), ([10], [3.]), ([4, 3, 2], [1.3, 1.5, 1.8])] rCoarseModPairs.append((range(NtCoarse / 2), [2] * NtCoarse)) rCoarseModPairs.append((range(NtCoarse / 2), [0.9] * NtCoarse)) rCoarseModPairs.append((range(NtCoarse / 2), [0.95] * NtCoarse)) for i, rCoarseModPair in zip(count(), rCoarseModPairs): for ind, val in zip(rCoarseModPair[0], rCoarseModPair[1]): rCoarse[ind] *= val aCoef = coef.coefficientCoarseFactor(NWorldCoarse, NCoarseElement, aBase, rCoarse) pglod.updateCorrectors(aCoef, clearFineQuantities=False) KmsFull = pglod.assembleMsStiffnessMatrix() 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 uLodFine = modifiedBasis * (xFull + g) gFine = basis * g uFineFull, AFine, MFine = femsolver.solveFine( world, aCoef.aFine, None, -gFine, boundaryConditions) uFineFull += gFine errorFineA = np.sqrt( np.dot(uFineFull - uLodFine, AFine * (uFineFull - uLodFine))) errorFineM = np.sqrt( np.dot(uFineFull - uLodFine, MFine * (uFineFull - uLodFine))) if firstIteration: self.assertTrue(np.isclose(errorFineA, 0)) self.assertTrue(np.isclose(errorFineM, 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)) firstIteration = False else: # For this problem, it seems that # error < 1.1*errorTol self.assertTrue(errorFineA <= 1.1 * epsilonTol)
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 result(pglod, world, CoefClass, A, f, MC=1, prob=100): NWorldFine = world.NWorldFine NWorldCoarse = world.NWorldCoarse NCoarseElement = world.NCoarseElement boundaryConditions = world.boundaryConditions NpFine = np.prod(NWorldFine + 1) NpCoarse = np.prod(NWorldCoarse + 1) plist = [0, 5, 10, 20, 30, 100] #### initial ##### xmLoda = np.zeros([MC, np.size(plist)]) xmVcLoda = np.zeros([MC, np.size(plist)]) xmLodVcLoda = np.zeros([MC, np.size(plist)]) ems = [] plottingx = np.zeros([MC - 1, np.size(plist)]) plottingy = np.zeros([MC - 1, np.size(plist)]) plottingz = np.zeros([MC - 1, np.size(plist)]) plotting2x = np.zeros([MC - 1, np.size(plist)]) plotting2y = np.zeros([MC - 1, np.size(plist)]) plotting2z = np.zeros([MC - 1, np.size(plist)]) plotting3x = np.zeros([MC - 1, np.size(plist)]) plotting3y = np.zeros([MC - 1, np.size(plist)]) plotting3z = np.zeros([MC - 1, np.size(plist)]) for i in range(0, MC): print(('_____Sample__ ' + str(i + 1) + '/' + str(MC) + ' ____')) R = CoefClass.RandomVanish(probfactor=prob, PartlyVanish=None, Original=True) ANew = R.flatten() ###### Reference solution ###### f_fine = np.ones(NpFine) uFineFem, AFine, MFine = femsolver.solveFine(world, ANew, f_fine, None, boundaryConditions) Anew = coef.coefficientFine(NWorldCoarse, NCoarseElement, ANew) ###### tolerance = 0 without computing ###### vis, eps = pglod.updateCorrectors(Anew, 0, clearFineQuantities=False, mc=True, Computing=None) print(('Affected correctors: ' + str(np.sum(vis)))) ##### VCLOD ###### uVc = [] updated = 0 for p in plist: print(('p = ' + str(p) + '%')) uVcLod, updated = VcLod(pglod, world, Anew, eps, updated, numberofcorrectors=p) if p == 100: uLod = uVcLod pglod.CorrectorsToOrigin() else: uVc.append(uVcLod) for k in range(0, np.shape(uVc)[0]): uVcLod = uVc[k] eVcLod = np.sqrt( np.dot(uFineFem - uVcLod, MFine * (uFineFem - uVcLod))) / np.sqrt( np.dot(uFineFem, MFine * uFineFem)) eLodVcLod = np.sqrt(np.dot(uVcLod - uLod, MFine * (uVcLod - uLod))) / np.sqrt( np.dot(uLod, MFine * uLod)) eLod = np.sqrt(np.dot(uFineFem - uLod, MFine * (uFineFem - uLod))) / np.sqrt( np.dot(uFineFem, MFine * uFineFem)) xmLoda[i, k] = eLod xmVcLoda[i, k] = eVcLod xmLodVcLoda[i, k] = eLodVcLod if i == 0: continue ems.append(i + 1) for k in range(0, np.shape(uVc)[0]): muLod = 0 muVcLod = 0 muLodVcLod = 0 for j in range(0, i + 1): muLod += xmLoda[j, k] muVcLod += xmVcLoda[j, k] muLodVcLod += xmLodVcLoda[j, k] muLod /= i + 1 muVcLod /= i + 1 muLodVcLod /= i + 1 sig2Lod = 0 sig2VcLod = 0 sig2LodVcLod = 0 for j in range(0, i + 1): sig2Lod += (xmLoda[j, k] - muLod)**(2) sig2VcLod += (xmVcLoda[j, k] - muVcLod)**(2) sig2LodVcLod += (xmLodVcLoda[j, k] - muLodVcLod)**(2) sig2Lod /= i sig2VcLod /= i sig2LodVcLod /= i a = [ np.sqrt(sig2Lod) / np.sqrt(i + 1) * 1.96, np.sqrt(sig2VcLod) / np.sqrt(i + 1) * 1.96, np.sqrt(sig2LodVcLod) / np.sqrt(i + 1) * 1.96 ] mum = [muLod, muVcLod, muLodVcLod] plottingx[i - 1, k] = mum[0] - a[0] plottingy[i - 1, k] = mum[0] plottingz[i - 1, k] = mum[0] + a[0] plotting2x[i - 1, k] = mum[1] - a[1] plotting2y[i - 1, k] = mum[1] plotting2z[i - 1, k] = mum[1] + a[1] plotting3x[i - 1, k] = mum[2] - a[2] plotting3y[i - 1, k] = mum[2] plotting3z[i - 1, k] = mum[2] + a[2] Matrix = CoefClass.Matrix.flatten() ROOT = '../test_data/MonteCarlo/Coef1/p' + str( 100 / prob) + '/' + str(plist[k]) safer(ROOT, mum, a, plottingx[:, k], plottingy[:, k], plottingz[:, k], plotting2x[:, k], plotting2y[:, k], plotting2z[:, k], plotting3x[:, k], plotting3y[:, k], plotting3z[:, k], ems, Matrix) return a, mum
f_reshaped = f.reshape(NFine + 1) # f_ref_reshaped[int(0*fine/8):int(2*fine/8),int(0*fine/8):int(2*fine/8)] = 1 # f_ref_reshaped[int(6*fine/8):int(8*fine/8),int(6*fine/8):int(8*fine/8)] = 1 f_reshaped[int(4 * fine / 8):int(5 * fine / 8), int(4 * fine / 8):int(5 * fine / 8)] = 10 f = f_reshaped.reshape(NpFine) plt.figure("Coefficient") drawCoefficient_origin(NFine, aFine) plt.figure('Right hand side') draw_f(NFine + 1, f) plt.show() uSol, AFine, _ = femsolver.solveFine(world, aFine, f, None, boundaryConditions) kList = [4] NList = [32] logH = {N: np.abs(np.log(np.sqrt(2 * (1. / N**2)))) for N in NList} for N in NList: print('___________________________________________________') for k in kList: print( ' k = {} H = 1/{} logH = {:3f} => k = {} should be sufficient' .format(k, N, logH[N], int(logH[N] + 0.99)), end='', flush=True) NWorldCoarse = np.array([N, N]) NCoarseElement = NFine // NWorldCoarse boundaryConditions = np.array([[0, 0], [0, 0]])