Пример #1
0
    def localize(self, iSubPatchCoarse, NSubPatchCoarse):
        # Either ._aBase or ._aFine exists, not both
        if not hasattr(self, '_aFine'):
            a = self._aBase
        else:
            a = self._aFine

        NPatchCoarse = self.NPatchCoarse
        NCoarseElement = self.NCoarseElement
        NPatchFine = NPatchCoarse*NCoarseElement
        NSubPatchFine = NSubPatchCoarse*NCoarseElement
        iSubPatchFine = iSubPatchCoarse*NCoarseElement

        # rCoarse
        coarseTIndexMap = util.lowerLeftpIndexMap(NSubPatchCoarse-1, NPatchCoarse-1)
        coarseTStartIndex = util.convertpCoordinateToIndex(NPatchCoarse-1, iSubPatchCoarse)
        rCoarseLocalized = self._rCoarse[coarseTStartIndex + coarseTIndexMap]

        # a
        coarsetIndexMap = util.lowerLeftpIndexMap(NSubPatchFine-1, NPatchFine-1)
        coarsetStartIndex = util.convertpCoordinateToIndex(NPatchFine-1, iSubPatchFine)
        aLocalized = a[coarsetStartIndex + coarsetIndexMap]

        localizedCoefficient = coefficientCoarseFactor(NSubPatchCoarse, NCoarseElement, None, rCoarseLocalized)
        if not hasattr(self, '_aFine'):
            localizedCoefficient._aBase = aLocalized
        else:
            localizedCoefficient._aFine = aLocalized
            del localizedCoefficient._aBase

        return localizedCoefficient
Пример #2
0
    def computeFaceFluxTF(self, u, f=None):
        assert (f is None)

        world = self.world
        NWorldCoarse = world.NWorldCoarse
        d = np.size(NWorldCoarse)
        NtCoarse = np.prod(NWorldCoarse)
        NpCoarse = np.prod(NWorldCoarse + 1)

        fluxTF = np.zeros([NtCoarse, 2 * d])

        elementpIndexMap = util.elementpIndexMap(NWorldCoarse)
        elementpStartIndices = util.lowerLeftpIndexMap(NWorldCoarse - 1,
                                                       NWorldCoarse)

        for TInd in np.arange(NtCoarse):
            ecT = self.ecList[TInd]
            assert (hasattr(ecT, 'csi'))

            patchtStartIndex = util.convertpCoordinateToIndex(
                NWorldCoarse - 1, ecT.iPatchWorldCoarse)
            patchtIndexMap = util.lowerLeftpIndexMap(ecT.NPatchCoarse - 1,
                                                     NWorldCoarse - 1)
            elementpIndex = elementpStartIndices[TInd] + elementpIndexMap

            patchtIndices = patchtStartIndex + patchtIndexMap
            fluxTF[TInd, :] += np.einsum('iF, i -> F', ecT.csi.basisFluxTF,
                                         u[elementpIndex])
            fluxTF[patchtIndices, :] -= np.einsum('iTF, i -> TF',
                                                  ecT.csi.correctorFluxTF,
                                                  u[elementpIndex])

        return fluxTF
Пример #3
0
    def computeCorrection(self, ARhsFull=None, MRhsFull=None):
        assert (self.ecList is not None)
        assert (self.coefficient is not None)

        world = self.world
        NCoarseElement = world.NCoarseElement
        NWorldCoarse = world.NWorldCoarse
        NWorldFine = NWorldCoarse * NCoarseElement

        NpFine = np.prod(NWorldFine + 1)

        coefficient = self.coefficient
        IPatchGenerator = self.IPatchGenerator

        localBasis = world.localBasis

        TpIndexMap = util.lowerLeftpIndexMap(NCoarseElement, NWorldFine)
        TpStartIndices = util.pIndexMap(NWorldCoarse - 1, NWorldFine,
                                        NCoarseElement)

        uFine = np.zeros(NpFine)

        NtCoarse = np.prod(world.NWorldCoarse)
        for TInd in range(NtCoarse):
            if self.printLevel > 0:
                print str(TInd) + ' / ' + str(NtCoarse)

            ecT = self.ecList[TInd]

            coefficientPatch = coefficient.localize(ecT.iPatchWorldCoarse,
                                                    ecT.NPatchCoarse)
            IPatch = IPatchGenerator(ecT.iPatchWorldCoarse, ecT.NPatchCoarse)

            if ARhsFull is not None:
                ARhsList = [ARhsFull[TpStartIndices[TInd] + TpIndexMap]]
            else:
                ARhsList = None

            if MRhsFull is not None:
                MRhsList = [MRhsFull[TpStartIndices[TInd] + TpIndexMap]]
            else:
                MRhsList = None

            correctorT = ecT.computeElementCorrector(coefficientPatch, IPatch,
                                                     ARhsList, MRhsList)[0]

            NPatchFine = ecT.NPatchCoarse * NCoarseElement
            iPatchWorldFine = ecT.iPatchWorldCoarse * NCoarseElement
            patchpIndexMap = util.lowerLeftpIndexMap(NPatchFine, NWorldFine)
            patchpStartIndex = util.convertpCoordinateToIndex(
                NWorldFine, iPatchWorldFine)

            uFine[patchpStartIndex + patchpIndexMap] += correctorT

        return uFine
Пример #4
0
    def computeErrorIndicatorFine(self, coefficientNew):
        assert (hasattr(self, 'fsi'))

        NPatchCoarse = self.NPatchCoarse
        world = self.world
        NCoarseElement = world.NCoarseElement
        NPatchFine = NPatchCoarse * NCoarseElement

        ALocFine = world.ALocFine
        P = world.localBasis

        a = coefficientNew.aFine
        aTilde = self.fsi.coefficient.aFine

        TFinetIndexMap = util.lowerLeftpIndexMap(NCoarseElement - 1,
                                                 NPatchFine - 1)
        iElementPatchFine = self.iElementPatchCoarse * NCoarseElement
        TFinetStartIndex = util.convertpCoordinateToIndex(
            NPatchFine - 1, iElementPatchFine)

        b = ((aTilde - a)**2) / a
        bT = b[TFinetStartIndex + TFinetIndexMap]
        PatchNorm = fem.assemblePatchMatrix(NPatchFine, ALocFine, b)
        TNorm = fem.assemblePatchMatrix(NCoarseElement, ALocFine, bT)

        BNorm = fem.assemblePatchMatrix(NCoarseElement, ALocFine,
                                        a[TFinetStartIndex + TFinetIndexMap])

        TFinepIndexMap = util.lowerLeftpIndexMap(NCoarseElement, NPatchFine)
        TFinepStartIndex = util.convertpCoordinateToIndex(
            NPatchFine, iElementPatchFine)

        Q = np.column_stack(self.fsi.correctorsList)
        QT = Q[TFinepStartIndex + TFinepIndexMap, :]

        A = np.dot((P - QT).T, TNorm * (P - QT)) + np.dot(Q.T, PatchNorm * Q)
        B = np.dot(P.T, BNorm * P)

        eigenvalues = scipy.linalg.eigvals(A[:-1, :-1], B[:-1, :-1])
        epsilonTSquare = np.max(np.real(eigenvalues))

        return np.sqrt(epsilonTSquare)
Пример #5
0
    def localize(self, iSubPatchCoarse, NSubPatchCoarse):
        NPatchCoarse = self.NPatchCoarse
        NCoarseElement = self.NCoarseElement
        NPatchFine = NPatchCoarse*NCoarseElement
        NSubPatchFine = NSubPatchCoarse*NCoarseElement
        iSubPatchFine = iSubPatchCoarse*NCoarseElement

        # a
        coarsetIndexMap = util.lowerLeftpIndexMap(NSubPatchFine-1, NPatchFine-1)
        coarsetStartIndex = util.convertpCoordinateToIndex(NPatchFine-1, iSubPatchFine)
        aFineLocalized = self._aFine[coarsetStartIndex + coarsetIndexMap]

        localizedCoefficient = coefficientFine(NSubPatchCoarse, NCoarseElement, aFineLocalized)
        return localizedCoefficient
Пример #6
0
    def assembleBasisCorrectors(self):
        if self.basisCorrectors is not None:
            return self.basisCorrectors

        assert (self.ecList is not None)

        world = self.world
        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 = []
        ecList = self.ecList
        for TInd in range(NtCoarse):
            ecT = ecList[TInd]
            assert (ecT is not None)
            assert (hasattr(ecT, 'fsi'))

            NPatchFine = ecT.NPatchCoarse * NCoarseElement
            iPatchWorldFine = ecT.iPatchWorldCoarse * NCoarseElement

            patchpIndexMap = util.lowerLeftpIndexMap(NPatchFine, NWorldFine)
            patchpStartIndex = util.convertpCoordinateToIndex(
                NWorldFine, iPatchWorldFine)

            colsT = TpStartIndices[TInd] + TpIndexMap
            rowsT = patchpStartIndex + patchpIndexMap
            dataT = np.hstack(ecT.fsi.correctorsList)

            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))

        self.basisCorrectors = basisCorrectors
        return basisCorrectors
Пример #7
0
    def assembleMsStiffnessMatrix(self):
        if self.Kms is not None:
            return self.Kms

        assert (self.ecList is not None)

        world = self.world
        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 = []
        ecList = self.ecList
        for TInd in range(NtCoarse):
            ecT = ecList[TInd]
            assert (ecT is not None)

            NPatchCoarse = ecT.NPatchCoarse

            patchpIndexMap = util.lowerLeftpIndexMap(NPatchCoarse,
                                                     NWorldCoarse)
            patchpStartIndex = util.convertpCoordinateToIndex(
                NWorldCoarse, ecT.iPatchWorldCoarse)

            colsT = TpStartIndices[TInd] + TpIndexMap
            rowsT = patchpStartIndex + patchpIndexMap
            dataT = ecT.csi.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))

        self.Kms = Kms
        return Kms
Пример #8
0
    def computeErrorIndicator(self, rCoarseNew):
        assert (hasattr(self, 'csi'))
        assert (self.csi.rCoarse is not None)

        world = self.world
        NPatchCoarse = self.NPatchCoarse
        NCoarseElement = world.NCoarseElement
        iElementPatchCoarse = self.iElementPatchCoarse

        elementCoarseIndex = util.convertpCoordinateToIndex(
            NPatchCoarse - 1, iElementPatchCoarse)

        rCoarse = self.csi.rCoarse
        muTPrime = self.csi.muTPrime
        deltaMaxNormTPrime = np.abs(
            (rCoarseNew - rCoarse) / np.sqrt(rCoarseNew * rCoarse))

        epsilonTSquare = rCoarseNew[elementCoarseIndex]/rCoarse[elementCoarseIndex] * \
                         np.sum((deltaMaxNormTPrime**2)*muTPrime)

        return np.sqrt(epsilonTSquare)
Пример #9
0
    def computeErrorIndicatorFineWithLagging(self, a, aTilde):
        assert (hasattr(self, 'csi'))

        world = self.world
        NPatchCoarse = self.NPatchCoarse
        NCoarseElement = world.NCoarseElement
        NPatchFine = NPatchCoarse * NCoarseElement
        iElementPatchCoarse = self.iElementPatchCoarse

        elementCoarseIndex = util.convertpCoordinateToIndex(
            NPatchCoarse - 1, iElementPatchCoarse)

        TPrimeFinetStartIndices = util.pIndexMap(NPatchCoarse - 1,
                                                 NPatchFine - 1,
                                                 NCoarseElement)
        TPrimeFinetIndexMap = util.lowerLeftpIndexMap(NCoarseElement - 1,
                                                      NPatchFine - 1)

        muTPrime = self.csi.muTPrime

        TPrimeIndices = np.add.outer(TPrimeFinetStartIndices,
                                     TPrimeFinetIndexMap)
        aTPrime = a[TPrimeIndices]
        aTildeTPrime = aTilde[TPrimeIndices]

        deltaMaxNormTPrime = np.max(np.abs(
            (aTPrime - aTildeTPrime) / np.sqrt(aTPrime * aTildeTPrime)),
                                    axis=1)
        theOtherUnnamedFactorTPrime = np.max(
            np.abs(aTPrime[elementCoarseIndex] /
                   aTildeTPrime[elementCoarseIndex]))

        epsilonTSquare = theOtherUnnamedFactorTPrime * \
                         np.sum((deltaMaxNormTPrime**2)*muTPrime)

        return np.sqrt(epsilonTSquare)
Пример #10
0
    def computeCoarseQuantities(self):
        '''Compute the coarse quantities K and L for this element corrector

        Compute the tensors (T is given by the class instance):

        KTij   = (A \nabla lambda_j, \nabla lambda_i)_{T}
        KmsTij = (A \nabla (lambda_j - Q_T lambda_j), \nabla lambda_i)_{U_k(T)}
        muTT'  = max_{w_H} || A \nabla (\chi_T - Q_T) w_H ||^2_T' / || A \nabla w_H ||^2_T

        and store them in the self.csi object. See
        notes/coarse_quantities*.pdf for a description.

        Auxiliary quantities are computed, but not saved, e.g.

        LTT'ij = (A \nabla (chi_T - Q_T)lambda_j, \nabla (chi_T - Q_T) lambda_j)_{T'}
        '''
        assert (hasattr(self, 'fsi'))

        world = self.world
        NCoarseElement = world.NCoarseElement
        NPatchCoarse = self.NPatchCoarse
        NPatchFine = NPatchCoarse * NCoarseElement

        NTPrime = np.prod(NPatchCoarse)
        NpPatchCoarse = np.prod(NPatchCoarse + 1)

        d = np.size(NPatchCoarse)

        correctorsList = self.fsi.correctorsList
        aPatch = self.fsi.coefficient.aFine

        ALocFine = world.ALocFine
        localBasis = world.localBasis

        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.convertpCoordinateToIndex(NPatchCoarse - 1,
                                              self.iElementPatchCoarse)

        QPatch = np.column_stack(correctorsList)

        # This loop can probably be done faster than this. If a bottle-neck, fix!
        Kmsij = np.zeros((NpPatchCoarse, 2**d))
        LTPrimeij = np.zeros((NTPrime, 2**d, 2**d))
        for (TPrimeInd,
             TPrimeCoarsepStartIndex,
             TPrimeFinetStartIndex,
             TPrimeFinepStartIndex) \
             in zip(np.arange(NTPrime),
                    TPrimeCoarsepStartIndices,
                    TPrimeFinetStartIndices,
                    TPrimeFinepStartIndices):

            aTPrime = aPatch[TPrimeFinetStartIndex + TPrimeFinetIndexMap]
            KTPrime = fem.assemblePatchMatrix(NCoarseElement, ALocFine,
                                              aTPrime)
            P = localBasis
            Q = QPatch[TPrimeFinepStartIndex + TPrimeFinepIndexMap, :]
            BTPrimeij = np.dot(P.T, KTPrime * Q)
            CTPrimeij = np.dot(Q.T, KTPrime * Q)
            sigma = TPrimeCoarsepStartIndex + TPrimeCoarsepIndexMap
            if TPrimeInd == TInd:
                Kij = np.dot(P.T, KTPrime * P)
                LTPrimeij[TPrimeInd] = CTPrimeij \
                                       - BTPrimeij \
                                       - BTPrimeij.T \
                                       + Kij
                Kmsij[sigma, :] += Kij - BTPrimeij

            else:
                LTPrimeij[TPrimeInd] = CTPrimeij
                Kmsij[sigma, :] += -BTPrimeij

        muTPrime = np.zeros(NTPrime)
        for TPrimeInd in np.arange(NTPrime):
            # Solve eigenvalue problem LTPrimeij x = mu_TPrime Mij x
            eigenvalues = scipy.linalg.eigvals(LTPrimeij[TPrimeInd][:-1, :-1],
                                               Kij[:-1, :-1])
            muTPrime[TPrimeInd] = np.max(np.real(eigenvalues))

        # Compute coarse element face flux for basis and Q (not yet implemented for R)
        correctorFluxTF = transport.computeHarmonicMeanFaceFlux(
            world.NWorldCoarse, NPatchCoarse, NCoarseElement, aPatch, QPatch)

        # Need to compute over at least one fine element over the
        # boundary of the main element to make the harmonic average
        # right.  Note: We don't do this for correctorFluxTF, beause
        # we do not have access to a outside the patch...
        localBasisExtended = np.zeros_like(QPatch)
        localBasisExtended[TPrimeFinepStartIndices[TInd] +
                           TPrimeFinepIndexMap, :] = localBasis
        basisFluxTF = transport.computeHarmonicMeanFaceFlux(
            world.NWorldCoarse, NPatchCoarse, NCoarseElement, aPatch,
            localBasisExtended)[:, TInd, :]

        if isinstance(self.fsi.coefficient,
                      coef.coefficientCoarseFactorAbstract):
            rCoarse = self.fsi.coefficient.rCoarse
        else:
            rCoarse = None
        self.csi = CoarseScaleInformation(Kij, Kmsij, muTPrime,
                                          correctorFluxTF, basisFluxTF,
                                          rCoarse)