def test_convertpLinearIndexToCoordIndex(self): N = np.array([100]) ind = np.array([44]) self.assertTrue(np.all(util.convertpLinearIndexToCoordIndex(N, ind) == [44])) N = np.array([100, 200]) ind = 44+55*101 self.assertTrue(np.all(util.convertpLinearIndexToCoordIndex(N, ind) == [44, 55]))
def assembleBasisCorrectors(world, patchT, basisCorrectorsListT, periodic=False): '''Compute the basis correctors given the elementwise basis correctors for each coarse element. Adapted from gridlod.pglod.assembleBasisCorrectors with newly added periodic functionality. In the periodic case, you are also allowed to hand over just a single basisCorrectorsList if these local correctors are the same for every element (e.g. for periodic coefficients). ''' NWorldCoarse = world.NWorldCoarse NCoarseElement = world.NCoarseElement NWorldFine = NWorldCoarse * NCoarseElement NtCoarse = np.prod(NWorldCoarse) NpCoarse = np.prod(NWorldCoarse + 1) NpFine = np.prod(NWorldFine + 1) TpIndexMap = util.lowerLeftpIndexMap(np.ones_like(NWorldCoarse), NWorldCoarse) TpStartIndices = util.lowerLeftpIndexMap(NWorldCoarse - 1, NWorldCoarse) cols = [] rows = [] data = [] for TInd in range(NtCoarse): if periodic and not (isinstance(basisCorrectorsListT, tuple)): # if only one CorrectorsList is given in periodic case basisCorrectorsList = basisCorrectorsListT else: basisCorrectorsList = basisCorrectorsListT[TInd] patch = patchT[TInd] NPatchFine = patch.NPatchCoarse * NCoarseElement iPatchWorldFine = patch.iPatchWorldCoarse * NCoarseElement patchpIndexMap = util.lowerLeftpIndexMap(NPatchFine, NWorldFine) patchpStartIndex = util.convertpCoordIndexToLinearIndex(NWorldFine, iPatchWorldFine) if periodic: rowsTpCoord = (iPatchWorldFine.T + util.convertpLinearIndexToCoordIndex(NWorldFine, patchpIndexMap).T) \ % NWorldFine rowsT = util.convertpCoordIndexToLinearIndex(NWorldFine, rowsTpCoord) colsTbase = TpStartIndices[TInd] + TpIndexMap colsTpCoord = util.convertpLinearIndexToCoordIndex(NWorldCoarse, colsTbase).T % NWorldCoarse colsT = util.convertpCoordIndexToLinearIndex(NWorldCoarse, colsTpCoord) else: colsT = TpStartIndices[TInd] + TpIndexMap rowsT = patchpStartIndex + patchpIndexMap dataT = np.hstack(basisCorrectorsList) cols.extend(np.repeat(colsT, np.size(rowsT))) rows.extend(np.tile(rowsT, np.size(colsT))) data.extend(dataT) basisCorrectors = sparse.csc_matrix((data, (rows, cols)), shape=(NpFine, NpCoarse)) return basisCorrectors
def assembleMsStiffnessMatrix(world, patchT, KmsijT, periodic=False): '''Compute the multiscale Petrov-Galerkin stiffness matrix given Kmsij for each coarse element. Adapted from gridlod.pglod.assembleMsStiffnessMatrix with newly added periodic functionality. In the periodic case, you are also allowed to hand over just a single Kmsij if this local matrix is the same for every element (e.g. for periodic coefficients). ''' NWorldCoarse = world.NWorldCoarse NtCoarse = np.prod(world.NWorldCoarse) NpCoarse = np.prod(world.NWorldCoarse + 1) TpIndexMap = util.lowerLeftpIndexMap(np.ones_like(NWorldCoarse), NWorldCoarse) TpStartIndices = util.lowerLeftpIndexMap(NWorldCoarse - 1, NWorldCoarse) cols = [] rows = [] data = [] for TInd in range(NtCoarse): if periodic and not ( isinstance(KmsijT, tuple) or isinstance(KmsijT, list)): # if only one matrix is given in periodic case Kmsij = KmsijT else: Kmsij = KmsijT[TInd] patch = patchT[TInd] NPatchCoarse = patch.NPatchCoarse patchpIndexMap = util.lowerLeftpIndexMap(NPatchCoarse, NWorldCoarse) patchpStartIndex = util.convertpCoordIndexToLinearIndex(NWorldCoarse, patch.iPatchWorldCoarse) if periodic: rowsTpCoord = (patch.iPatchWorldCoarse.T + util.convertpLinearIndexToCoordIndex(NWorldCoarse, patchpIndexMap).T) \ % NWorldCoarse rowsT = util.convertpCoordIndexToLinearIndex(NWorldCoarse, rowsTpCoord) colsTbase = TpStartIndices[TInd] + TpIndexMap colsTpCoord = util.convertpLinearIndexToCoordIndex(NWorldCoarse, colsTbase).T % NWorldCoarse colsT = util.convertpCoordIndexToLinearIndex(NWorldCoarse, colsTpCoord) else: rowsT = patchpStartIndex + patchpIndexMap colsT = TpStartIndices[TInd] + TpIndexMap dataT = Kmsij.flatten() cols.extend(np.tile(colsT, np.size(rowsT))) rows.extend(np.repeat(rowsT, np.size(colsT))) data.extend(dataT) Kms = sparse.csc_matrix((data, (rows, cols)), shape=(NpCoarse, NpCoarse)) return Kms
def __init__(self, world, k, TInd): self.world = world self.k = k self.TInd = TInd assert(2*k+1 <= np.min(world.NWorldCoarse)) iElementWorldCoarse = util.convertpLinearIndexToCoordIndex(world.NWorldCoarse - 1, TInd)[:] self.iElementWorldCoarse = iElementWorldCoarse # Compute (NPatchCoarse, iElementPatchCoarse) from (k, iElementWorldCoarse, NWorldCoarse) d = np.size(iElementWorldCoarse) NWorldCoarse = world.NWorldCoarse iPatchWorldCoarse = (iElementWorldCoarse - k).astype('int64') self.iElementPatchCoarse = iElementWorldCoarse - iPatchWorldCoarse for i in range(d): if iPatchWorldCoarse[i] < 0: iPatchWorldCoarse[i] += NWorldCoarse[i] self.NPatchCoarse = (2*k + 1)*np.ones(d, dtype='int64') self.iPatchWorldCoarse = iPatchWorldCoarse self.NPatchFine = self.NPatchCoarse * world.NCoarseElement self.NpFine = np.prod(self.NPatchFine + 1) self.NtFine = np.prod(self.NPatchFine) self.NpCoarse = np.prod(self.NPatchCoarse + 1) self.NtCoarse = np.prod(self.NPatchCoarse)
def checkerboardI(ii): coeff = alpha * np.ones(NtFine) #find out which indices on fine grid correspond to element ii on epsilon grid elementIndex = util.convertpLinearIndexToCoordIndex(Nepsilon - 1, ii)[:] indices = util.extractElementFine(Nepsilon, NFineElement // NepsilonElement, elementIndex) coeff[indices] = beta return coeff
def originCorrectors(self, clearFineQuantities=True): world = self.world k = self.k IPatchGenerator = self.IPatchGenerator coefficient = self.origincoef NtCoarse = np.prod(world.NWorldCoarse) # Reset all caches self.Kms = None self.K = None self.basisCorrectors = None self.ecListOrigin = [None] * NtCoarse if self.printLevel >= 2: print('Setting up workers for origin Correctors') eccontroller.setupWorker(world, coefficient, IPatchGenerator, k, clearFineQuantities, self.printLevel) if self.printLevel >= 2: print('Done') #element corrector list has coarse element size ecListOrigin = self.ecListOrigin ecComputeList = [] for TInd in range(NtCoarse): iElement = util.convertpLinearIndexToCoordIndex( world.NWorldCoarse - 1, TInd) ecComputeList.append((TInd, iElement)) if self.printLevel >= 2: print('Waiting for results', len(ecComputeList)) ecResultList = eccontroller.mapComputations(ecComputeList, self.printLevel) for ecResult, ecCompute in zip(ecResultList, ecComputeList): ecListOrigin[ecCompute[0]] = ecResult self.ecList = deepcopy(ecListOrigin) self.ecListtesting = deepcopy(ecListOrigin)
def compute_basis_correctors(self): ''' Computes the basis correctors Q_T\lambda_x for every element T. ''' world = self.world k = self.k IPatchGenerator = self.IPatchGenerator b_coef = self.b_coef a_coef = self.a_coef NtCoarse = np.prod(world.NWorldCoarse) ecListOrigin = [None] * NtCoarse ecComputeList = [] for element_index in range(NtCoarse): iElement = util.convertpLinearIndexToCoordIndex( world.NWorldCoarse - 1, element_index) ecComputeList.append((element_index, iElement)) ecTList = [] for element_index, iElement in ecComputeList: ecT = lod_element.elementCorrector(world, k, iElement) b_patch = b_coef.localize(ecT.iPatchWorldCoarse, ecT.NPatchCoarse) a_patch = a_coef.localize(ecT.iPatchWorldCoarse, ecT.NPatchCoarse) IPatch = IPatchGenerator(ecT.iPatchWorldCoarse, ecT.NPatchCoarse) ecT.compute_corrector(b_patch, a_patch, IPatch) ecTList.append(ecT) for ecResult, ecCompute in zip(ecTList, ecComputeList): ecListOrigin[ecCompute[0]] = ecResult self.ecList = deepcopy(ecListOrigin)
def localizeCoefficient(patch, aFine, periodic=False): ''' localizes a coefficient aFine to patch. Optional argument whether erveything is to be interpreted in periodic manner. Adapted from gridlod.coef.localizeCoefficient, periodicty functionality is newly added''' iPatchWorldCoarse = patch.iPatchWorldCoarse NPatchCoarse = patch.NPatchCoarse NCoarseElement = patch.world.NCoarseElement NPatchFine = NPatchCoarse * NCoarseElement iPatchWorldFine = iPatchWorldCoarse * NCoarseElement NWorldFine = patch.world.NWorldFine NtPatchFine = np.prod(NPatchFine) d = np.size(iPatchWorldCoarse) # a coarsetIndexMap = util.lowerLeftpIndexMap(NPatchFine - 1, NWorldFine - 1) coarsetStartIndex = util.convertpCoordIndexToLinearIndex(NWorldFine - 1, iPatchWorldFine) if periodic: coarsetIndCoord = (iPatchWorldFine.T + util.convertpLinearIndexToCoordIndex(NWorldFine - 1, coarsetIndexMap).T) \ % NWorldFine coarsetIndices = util.convertpCoordIndexToLinearIndex(NWorldFine - 1, coarsetIndCoord) aFineLocalized = aFine[coarsetIndices] else: aFineLocalized = aFine[coarsetStartIndex + coarsetIndexMap] return aFineLocalized
def performTPrimeLoop_helmholtz(patch, lambdasList, correctorsList, aPatch, kPatch, k2Patch, accumulate): while callable(aPatch): aPatch = aPatch() while callable(kPatch): kPatch = kPatch() while callable(k2Patch): k2Patch = k2Patch() world = patch.world NCoarseElement = world.NCoarseElement NPatchCoarse = patch.NPatchCoarse NPatchFine = NPatchCoarse * NCoarseElement NTPrime = np.prod(NPatchCoarse) NpPatchCoarse = np.prod(NPatchCoarse + 1) d = np.size(NPatchCoarse) assert (aPatch.ndim == 1 or aPatch.ndim == 3) assert (kPatch.ndim == 1) assert (k2Patch.ndim == 1) if aPatch.ndim == 1: ALocFine = world.ALocFine elif aPatch.ndim == 3: ALocFine = world.ALocMatrixFine MLocFine = world.MLocFine BdLocFine = fem.localBoundaryMassMatrixGetter(NCoarseElement * world.NWorldCoarse) lambdas = np.column_stack(lambdasList) numLambdas = len(lambdasList) TPrimeCoarsepStartIndices = util.lowerLeftpIndexMap( NPatchCoarse - 1, NPatchCoarse) TPrimeCoarsepIndexMap = util.lowerLeftpIndexMap(np.ones_like(NPatchCoarse), NPatchCoarse) TPrimeFinetStartIndices = util.pIndexMap(NPatchCoarse - 1, NPatchFine - 1, NCoarseElement) TPrimeFinetIndexMap = util.lowerLeftpIndexMap(NCoarseElement - 1, NPatchFine - 1) TPrimeFinepStartIndices = util.pIndexMap(NPatchCoarse - 1, NPatchFine, NCoarseElement) TPrimeFinepIndexMap = util.lowerLeftpIndexMap(NCoarseElement, NPatchFine) TInd = util.convertpCoordIndexToLinearIndex(NPatchCoarse - 1, patch.iElementPatchCoarse) QPatch = np.column_stack(correctorsList) # global boundary bdMapWorld = world.boundaryConditions == 1 for (TPrimeInd, TPrimeCoarsepStartIndex, TPrimeFinetStartIndex, TPrimeFinepStartIndex) \ in zip(np.arange(NTPrime), TPrimeCoarsepStartIndices, TPrimeFinetStartIndices, TPrimeFinepStartIndices): aTPrime = aPatch[TPrimeFinetStartIndex + TPrimeFinetIndexMap] kTPrime = kPatch[TPrimeFinetStartIndex + TPrimeFinetIndexMap] k2TPrime = k2Patch[TPrimeFinetStartIndex + TPrimeFinetIndexMap] KTPrime = fem.assemblePatchMatrix(NCoarseElement, ALocFine, aTPrime) MTPrime = fem.assemblePatchMatrix(NCoarseElement, MLocFine, k2TPrime) L2TPrime = fem.assemblePatchMatrix(NCoarseElement, MLocFine) # boundary on element bdMapElement = np.zeros([d, 2], dtype='bool') iElementTPrime = patch.iPatchWorldCoarse + util.convertpLinearIndexToCoordIndex( NPatchCoarse - 1, TPrimeInd) inheritElement0 = iElementTPrime == 0 inheritElement1 = (iElementTPrime + np.ones(d)) == world.NWorldCoarse bdMapElement[inheritElement0, 0] = bdMapWorld[inheritElement0, 0] bdMapElement[inheritElement1, 1] = bdMapWorld[inheritElement1, 1] BdTPrime = fem.assemblePatchBoundaryMatrix(NCoarseElement, BdLocFine, kTPrime, bdMapElement) P = lambdas Q = QPatch[TPrimeFinepStartIndex + TPrimeFinepIndexMap, :] _KTPrimeij = np.dot(P.T, KTPrime * Q) TPrimei = TPrimeCoarsepStartIndex + TPrimeCoarsepIndexMap _MTPrimeij = np.dot(P.T, MTPrime * Q) _BdTPrimeij = np.dot(P.T, BdTPrime * Q) CTPrimeij = np.dot(Q.T, L2TPrime * Q) BTPrimeij = np.dot(P.T, L2TPrime * Q) accumulate(TPrimeInd, TPrimei, P, Q, KTPrime, _KTPrimeij, MTPrime, BdTPrime, _MTPrimeij, _BdTPrimeij, L2TPrime, CTPrimeij, BTPrimeij)
def updateCorrectors(self, coefficient, epsilonTol, clearFineQuantities=True, Testing=None, Computing=True, mc=0, new_correctors=False, runtime=False): assert (self.ecListOrigin is not None) # Note: most of the optional arguments of this function are used for purposes of the Masterthesis. # it became quite much and unsorted. start = timeit.default_timer() world = self.world k = self.k IPatchGenerator = self.IPatchGenerator NtCoarse = np.prod(world.NWorldCoarse) # Reset all caches self.Kms = None self.K = None self.basisCorrectors = None self.ageList = [0] * NtCoarse if self.epsilonList == None: self.epsilonList = [np.nan] * NtCoarse if Testing: ecListOrigin = self.ecListtesting else: ecListOrigin = self.ecListOrigin ecList = deepcopy(ecListOrigin) if new_correctors: ecListOrigin = self.ecList if self.printLevel >= 2: print('Setting up workers') eccontroller.setupWorker(world, coefficient, IPatchGenerator, k, clearFineQuantities, self.printLevel) if self.printLevel >= 2: print('Done') #For coarse coefficient if self.ecList is not None and hasattr(coefficient, 'rCoarse'): ANew = coefficient.aFine AOld = deepcopy(self.origincoef.aFine) if ANew.ndim == 1: delta = np.abs((AOld - ANew) / np.sqrt(AOld * ANew)) else: delta = np.abs((AOld - ANew) * np.linalg.inv(np.sqrt(AOld)) * np.linalg.inv(np.sqrt(ANew))) ageList = self.ageList if epsilonTol == 0: epsilonList = self.epsilonList else: epsilonList = deepcopy(self.epsilonList) recomputeCount = 0 ecComputeList = [] for TInd in range(NtCoarse): if self.printLevel >= 3: print(str(TInd) + ' / ' + str(NtCoarse), end=' ') ageList[TInd] += 1 #mapper iElement = util.convertpLinearIndexToCoordIndex( world.NWorldCoarse - 1, TInd) ecT = ecListOrigin[TInd] if Testing: epsilonT = epsilonList[TInd] else: if hasattr(coefficient, 'aLagging'): coefficientPatch = coefficient.localize( ecT.iPatchWorldCoarse, ecT.NPatchCoarse) epsilonT = ecList[ TInd].computeErrorIndicatorFineWithLagging( coefficientPatch.aFine, coefficientPatch.aLagging) if hasattr(coefficient, 'rCoarse'): epsilonT = ecListOrigin[ TInd].computeLocalCoarseErrorIndicator(delta) elif hasattr(ecT, 'fsi'): coefficientPatch = coefficient.localize( ecT.iPatchWorldCoarse, ecT.NPatchCoarse) epsilonT = ecListOrigin[TInd].computeErrorIndicatorFine( coefficientPatch) epsilonList[TInd] = epsilonT if self.printLevel >= 2: print('epsilonT = ' + str(epsilonT), end=' ') if epsilonT > epsilonTol: if self.printLevel >= 2: print('C') if Testing: epsilonList[TInd] = 0 self.currentTestingCorrector = TInd ecComputeList.append((TInd, iElement)) ecList[TInd] = None ageList[TInd] = 0 recomputeCount += 1 else: if self.printLevel > 1: print('N') time_to_compute = timeit.default_timer() - start if self.printLevel >= 2: print('Waiting for results', len(ecComputeList)) if self.printLevel > 0 or Testing: if mc == 0: print("To be recomputed: ", float(recomputeCount) / NtCoarse * 100, '%') self.printLevel = 0 if Computing: ecResultList = eccontroller.mapComputations( ecComputeList, self.printLevel) for ecResult, ecCompute in zip(ecResultList, ecComputeList): ecList[ecCompute[0]] = ecResult else: if self.printLevel >= 1: print("Not Recomputed!") if Computing: self.ecList = ecList if epsilonTol != 0: self.ecListtesting = ecList if Testing: self.epsilonList = epsilonList ageListinv = np.ones(np.size(ageList)) ageListinv = ageListinv - ageList if runtime: return ageListinv, time_to_compute else: return ageListinv, epsilonList