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))
# coarse mesh parameters NWorldCoarse = np.array([N]) NCoarseElement = NFine / NWorldCoarse world = World(NWorldCoarse, NCoarseElement, boundaryConditions) # grid nodes xpCoarse = util.pCoordinates(NWorldCoarse).flatten() NpCoarse = np.prod(NWorldCoarse + 1) ''' Compute multiscale basis ''' # patch generator and coefficients IPatchGenerator = lambda i, N: interp.L2ProjectionPatchMatrix( i, N, NWorldCoarse, NCoarseElement, boundaryConditions) 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 system fs_solutions[i] = {w^i_x}_x
###### precompute ####### 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) #old Coefficient (need flatten form) ABase = A.flatten() Aold = coef.coefficientFine(NWorldCoarse, NCoarseElement, ABase) pglod = pg_pert.PerturbedPetrovGalerkinLOD(Aold, world, k, IPatchGenerator, 0) pglod.originCorrectors(clearFineQuantities=False) #Perturbations print('_____________ 1% Perturbations __________') prob = 100 MC = 100 a, mum = result(pglod, world, CoefClass, A, f, MC, prob) #Perturbations print('_____________ 2% Perturbations __________') prob = 50
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
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) # reference solution f_fine = np.ones(NpFine) uFineFem, AFine, MFine = femsolver.solveFine(world, ANew, f_fine, None, boundaryConditions) # 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 uLodFineWorst = uLodFine # energy error errorworst = np.sqrt( np.dot(uFineFem - uLodFineWorst, AFine * (uFineFem - uLodFineWorst))) # tolerance = 0 vis, eps = pglod.updateCorrectors(Anew, 0, clearFineQuantities=False, Computing=False) 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 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 + " ---- ", end=' ') vistol, _ = pglod.updateCorrectors(Anew, tol, clearFineQuantities=False, Testing=True) 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))) for k in range(leng - 1, -1, -1): errorBest.append(errorbest) errorWorst.append(errorworst) return vis, eps, PotentialCorrectors, recomputefractionsafe, errorplotinfo, errorWorst, errorBest