예제 #1
0
    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
예제 #6
0
    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)
예제 #7
0
파일: lod_wave.py 프로젝트: ollema/lod-wave
    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
예제 #9
0
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)
예제 #10
0
    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