print() KFull = pglod.assembleMsStiffnessMatrix(world, patchT, KmsijT) RFull = pglod.assemblePatchFunction(world, patchT, RmsiT) MFull = fem.assemblePatchMatrix(world.NWorldFine, world.MLocFine) Rf = pglod.assemblePatchFunction(world, patchT, correctorRhsT) basis = fem.assembleProlongationMatrix(world.NWorldCoarse, world.NCoarseElement) bFull = basis.T * MFull * f_trans - RFull basisCorrectors = pglod.assembleBasisCorrectors(world, patchT, correctorsListT) modifiedBasis = basis - basisCorrectors uFull, _ = pglod.solve(world, KFull, bFull, boundaryConditions) uLodFine = modifiedBasis * uFull uLodFine += Rf u_best_LOD = uLodFine energy_norm = np.sqrt(np.dot(u_best_LOD, AFine_trans * u_best_LOD)) energy_error = np.sqrt(np.dot((uFineFull_trans - u_best_LOD), AFine_trans * (uFineFull_trans - u_best_LOD))) print("Energy norm {}, error {}, rel. error {}".format(energy_norm, energy_error, energy_error/energy_norm)) # Use mapper to distribute computations (mapper could be the 'map' built-in or e.g. an ipyparallel map) print('computing correctors', end='', flush=True) patchT, correctorsListT, KmsijT, csiT = zip(*map(computeKmsij, range(world.NtCoarse))) print()
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 StartAlgorithm(self): assert (self.init) # only start the algorithm once # in case not every element is affected, the percentage would be missleading. eps_size = np.size(self.E_vh) self.E_vh = { i: self.E_vh[i] for i in range(np.size(self.E_vh)) if self.E_vh[i] > 0 } list = [v for v in self.E_vh.values()] list.append(0) tols = np.sort(list)[::-1] eps_size_f = np.size(self.E_vh) self.E_f = { i: self.E_f[i] for i in range(np.size(self.E_f)) if self.E_f[i] > 0 } list_f = [v for v in self.E_f.values()] list_f.append(0) tols_f = np.sort(list)[::-1] # make sure we only update one element all the time for i in range(1, np.size(tols)): if tols[i] == tols[i - 1]: tols[i] -= 1e-7 for i in range(1, np.size(tols_f)): if tols_f[i] == tols_f[i - 1]: tols_f[i] -= 1e-7 full_percentage = len(self.E_vh) / eps_size full_percentage_f = len(self.E_f) / eps_size_f world = self.world print('starting algorithm ...... ') TOLt = [] to_be_updatedT = [] energy_errorT = [] rel_energy_errorT = [] tmp_errorT = [] offset = [] TOL = 100 # not relevant for i in range(np.size(tols)): if TOL == 0: pass else: TOL = tols[i] TOLt.append(TOL) offset = self.UpdateNextElement(TOL, offset, Printing=False) if self.init: to_be_updated = np.size(offset) / len(self.E_vh) * 100 to_be_updatedT.append(to_be_updated) pass else: to_be_updated = np.size(offset) / len(self.E_vh) * 100 to_be_updatedT.append(to_be_updated * full_percentage) KFull = pglod.assembleMsStiffnessMatrix(world, self.patchT, self.KmsijT) RFull = pglod.assemblePatchFunction(world, self.patchT, self.RmsijT) Rf = pglod.assemblePatchFunction(world, self.patchT, self.correctorsRhsT) basis = fem.assembleProlongationMatrix(world.NWorldCoarse, world.NCoarseElement) bFull = basis.T * self.MFull * self.f_trans - RFull basisCorrectors = pglod.assembleBasisCorrectors( world, self.patchT, self.correctorsListT) modifiedBasis = basis - basisCorrectors uFull, _ = pglod.solve(world, KFull, bFull, self.boundaryConditions) uLodFine = modifiedBasis * uFull uLodFine += Rf uFineFull_trans_LOD = uLodFine if self.init: self.init = 0 uFineFull_trans_LOD_old = uLodFine energy_norm = np.sqrt( np.dot(uFineFull_trans_LOD, self.AFine_trans * uFineFull_trans_LOD)) # tmp_error tmp_energy_error = np.sqrt( np.dot((uFineFull_trans_LOD - uFineFull_trans_LOD_old), self.AFine_trans * (uFineFull_trans_LOD - uFineFull_trans_LOD_old))) # actual error if self.compare_with_best_LOD: energy_error = np.sqrt( np.dot((uFineFull_trans_LOD - self.u_best_LOD), self.AFine_trans * (uFineFull_trans_LOD - self.u_best_LOD))) else: energy_error = np.sqrt( np.dot((uFineFull_trans_LOD - self.uFineFull_trans), self.AFine_trans * (uFineFull_trans_LOD - self.uFineFull_trans))) uFineFull_trans_LOD_old = uFineFull_trans_LOD print( ' step({:3d}/{}) TOL: {:f}, updates: {:7.3f}%, energy error: {:f}, tmp_error: {:f}, relative energy error: {:f}' .format(i, np.size(tols), TOL, to_be_updated * full_percentage, energy_error, tmp_energy_error, energy_error / energy_norm)) rel_energy_errorT.append(energy_error / energy_norm) energy_errorT.append(energy_error) tmp_errorT.append(tmp_energy_error) if TOL == 0: # stop now break return to_be_updatedT, energy_errorT, tmp_errorT, rel_energy_errorT, TOLt, uFineFull_trans_LOD
def StartAlgorithm(self): assert (self.init) # only start the algorithm once # in case not every element is affected, the percentage would be missleading. eps_size = np.size(self.E_vh) self.E_vh = { i: self.E_vh[i] for i in range(np.size(self.E_vh)) if self.E_vh[i] > 0 } full_percentage = len(self.E_vh) / eps_size world = self.world print('starting algorithm ...... ') TOLt = [] to_be_updatedT = [] energy_errorT = [] rel_energy_errorT = [] tmp_errorT = [] offset = [] TOL = 100 # not relevant for i in range(len(self.E_vh) + 1): if self.init: pass else: offset = self.UpdateNextElement(offset, Printing=False) if self.init: to_be_updated = np.size(offset) / len(self.E_vh) * 100 to_be_updatedT.append(to_be_updated) pass else: to_be_updated = np.size(offset) / len(self.E_vh) * 100 to_be_updatedT.append(to_be_updated * full_percentage) KFull = pglod.assembleMsStiffnessMatrix(world, self.patchT, self.KmsijT) RFull = pglod.assemblePatchFunction(world, self.patchT, self.RmsijT) Rf = pglod.assemblePatchFunction(world, self.patchT, self.correctorsRhsT) basis = fem.assembleProlongationMatrix(world.NWorldCoarse, world.NCoarseElement) bFull = basis.T * self.MFull * self.f_trans - RFull basisCorrectors = pglod.assembleBasisCorrectors( world, self.patchT, self.correctorsListT) modifiedBasis = basis - basisCorrectors uFull, _ = pglod.solve(world, KFull, bFull, self.boundaryConditions) uLodFine = modifiedBasis * uFull uLodFine += Rf uFineFull_trans_LOD = uLodFine if self.init: uFineFull_trans_LOD_old = uLodFine energy_norm = np.sqrt( np.dot(uFineFull_trans_LOD, self.AFine_trans * uFineFull_trans_LOD)) # tmp_error tmp_energy_error = np.sqrt( np.dot((uFineFull_trans_LOD - uFineFull_trans_LOD_old), self.AFine_trans * (uFineFull_trans_LOD - uFineFull_trans_LOD_old))) # actual error if self.compare_with_best_LOD: energy_error = np.sqrt( np.dot((uFineFull_trans_LOD - self.u_best_LOD), self.AFine_trans * (uFineFull_trans_LOD - self.u_best_LOD))) else: energy_error = np.sqrt( np.dot((uFineFull_trans_LOD - self.uFineFull_trans), self.AFine_trans * (uFineFull_trans_LOD - self.uFineFull_trans))) uFineFull_trans_LOD_old = uFineFull_trans_LOD if self.init: self.init = 0 print( ' step({:3d}/{}) T: {} updates: {:7.3f}%, energy error: {:f}, tmp_error: {:f}, relative energy error: {:f}' .format(i, len(self.E_vh), ' - ', to_be_updated * full_percentage, energy_error, tmp_energy_error, energy_error / energy_norm)) else: print( ' step({:3d}/{}) T: {:3d} updates: {:7.3f}%, energy error: {:f}, tmp_error: {:f}, relative energy error: {:f}' .format(i, len(self.E_vh), offset[-1], to_be_updated * full_percentage, energy_error, tmp_energy_error, energy_error / energy_norm)) rel_energy_errorT.append(energy_error / energy_norm) energy_errorT.append(energy_error) tmp_errorT.append(tmp_energy_error) return to_be_updatedT, energy_errorT, tmp_errorT, rel_energy_errorT, TOLt, uFineFull_trans_LOD
def StartAlgorithm(self): assert (self.init) # only start the algorithm once # in case not every element is affected, the percentage would be missleading. eps_size = np.size(self.E_vh) self.E_vh = { i: self.E_vh[i] for i in range(np.size(self.E_vh)) if self.E_vh[i] > 0 } full_percentage = len(self.E_vh) / eps_size world = self.world print('starting algorithm ...... ') TOL = self.StartingTolerance TOLt = [] to_be_updatedT = [] energy_errorT = [] rel_energy_errorT = [] tmp_errorT = [] offset = [] continue_computing = 1 while continue_computing: TOLt.append(TOL) offset, computed = self.UpdateElements(TOL, offset, Printing=False) if computed: pass else: if self.init: pass else: to_be_updated = np.size(offset) / len(self.E_vh) * 100 to_be_updatedT.append(to_be_updated * full_percentage) energy_errorT.append(energy_error) tmp_errorT.append(old_tmp_energy_error) if np.size(offset) / len(self.E_vh) == 1: print(' every corrector has been updated') continue_computing = 0 continue else: print(' skipping TOL {}'.format(TOL)) TOL *= 3 / 4. continue to_be_updated = np.size(offset) / len(self.E_vh) * 100 to_be_updatedT.append(to_be_updated * full_percentage) KFull = pglod.assembleMsStiffnessMatrix(world, self.patchT, self.KmsijT) RFull = pglod.assemblePatchFunction(world, self.patchT, self.RmsijT) Rf = pglod.assemblePatchFunction(world, self.patchT, self.correctorsRhsT) basis = fem.assembleProlongationMatrix(world.NWorldCoarse, world.NCoarseElement) bFull = basis.T * self.MFull * self.f_trans - RFull basisCorrectors = pglod.assembleBasisCorrectors( world, self.patchT, self.correctorsListT) modifiedBasis = basis - basisCorrectors uFull, _ = pglod.solve(world, KFull, bFull, self.boundaryConditions) uLodFine = modifiedBasis * uFull uLodFine += Rf uFineFull_trans_LOD = uLodFine if self.init: uFineFull_trans_LOD_old = uLodFine self.init = 0 energy_norm = np.sqrt( np.dot(uFineFull_trans_LOD, self.AFine_trans * uFineFull_trans_LOD)) # tmp_error tmp_energy_error = np.sqrt( np.dot((uFineFull_trans_LOD - uFineFull_trans_LOD_old), self.AFine_trans * (uFineFull_trans_LOD - uFineFull_trans_LOD_old))) old_tmp_energy_error = tmp_energy_error # actual error energy_error = np.sqrt( np.dot((uFineFull_trans_LOD - self.uFineFull_trans), self.AFine_trans * (uFineFull_trans_LOD - self.uFineFull_trans))) uFineFull_trans_LOD_old = uFineFull_trans_LOD print( ' TOL: {:f}, updates: {:7.3f}%, energy error: {:f}, tmp_error: {:f}, relative energy error: {:f}' .format(TOL, to_be_updated * full_percentage, energy_error, tmp_energy_error, energy_error / energy_norm)) rel_energy_errorT.append(energy_error / energy_norm) energy_errorT.append(energy_error) tmp_errorT.append(tmp_energy_error) if tmp_energy_error > 1e-5: TOL *= 3 / 4. else: if int(np.size(offset) / len(self.E_vh)) == 1: if computed: print(' stop computing') continue_computing = 0 return to_be_updatedT, energy_errorT, tmp_errorT, rel_energy_errorT, TOLt, uFineFull_trans_LOD