コード例 #1
0
ファイル: test_util.py プロジェクト: fredrikhellman/gridlod
    def test_convertpCoordIndexToLinearIndex(self):
        N = np.array([100])
        coord = np.array([44])
        self.assertTrue(util.convertpCoordIndexToLinearIndex(N, coord) == 44)

        N = np.array([100, 200])
        coord = np.array([44, 55])
        self.assertTrue(util.convertpCoordIndexToLinearIndex(N, coord) == 44+55*101)
コード例 #2
0
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
コード例 #3
0
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
コード例 #4
0
ファイル: test_util.py プロジェクト: fredrikhellman/gridlod
    def test_tCoordinates(self):
        NWorld = np.array([5])
        xt = util.tCoordinates(NWorld)
        self.assertTrue(np.isclose(np.max(np.abs(xt.T - np.array([1., 3., 5., 7., 9.])/10)), 0))

        NWorld = np.array([9, 9, 9, 9])
        xt = util.tCoordinates(NWorld)
        ind = util.convertpCoordIndexToLinearIndex(NWorld-1, [7, 3, 6, 0])
        self.assertTrue(np.allclose(xt[ind] - np.array([15., 7., 13., 1.])/18., 0))
コード例 #5
0
ファイル: test_util.py プロジェクト: fredrikhellman/gridlod
    def test_pCoordinates(self):
        NWorld = np.array([5])
        xp = util.pCoordinates(NWorld)
        self.assertTrue(np.allclose(xp.T - np.array([0., 1., 2., 3., 4., 5.])/5, 0))

        NWorld = np.array([9, 9, 9, 9])
        xp = util.pCoordinates(NWorld)
        ind = util.convertpCoordIndexToLinearIndex(NWorld, [7, 3, 6, 0])
        self.assertTrue(np.allclose(xp[ind] - np.array([7., 3., 6., 0.])/9., 0))
コード例 #6
0
    def test_computeFullDomain(self):
        NWorldCoarse = np.array([1, 1, 1], dtype='int64')
        NCoarseElement = np.array([4, 2, 3], dtype='int64')
        NWorldFine = NWorldCoarse*NCoarseElement

        np.random.seed(0)

        world = World(NWorldCoarse, NCoarseElement)
        d = np.size(NWorldCoarse)
        k = np.max(NWorldCoarse)
        IWorld = interp.nodalPatchMatrix(Patch(world, k, 0))
        aWorld = np.exp(np.random.rand(world.NtFine))

        elementpIndexMap = util.lowerLeftpIndexMap(np.ones_like(NWorldCoarse), NWorldCoarse)
        elementpIndexMapFine = util.lowerLeftpIndexMap(NCoarseElement, NWorldFine)
        
        coarsepBasis = util.linearpIndexBasis(NWorldCoarse)
        finepBasis = util.linearpIndexBasis(NWorldFine)

        correctors = np.zeros((world.NpFine, world.NpCoarse))
        basis = np.zeros((world.NpFine, world.NpCoarse))
        
        for iElementWorldCoarse in it.product(*[np.arange(n, dtype='int64') for n in NWorldCoarse]):
            iElementWorldCoarse = np.array(iElementWorldCoarse)
            TInd = util.convertpCoordIndexToLinearIndex(NWorldCoarse, iElementWorldCoarse)
            patch = Patch(world, k, TInd)
            
            correctorsList = lod.computeBasisCorrectors(patch, IWorld, aWorld)
            
            worldpIndices = np.dot(coarsepBasis, iElementWorldCoarse) + elementpIndexMap
            correctors[:,worldpIndices] += np.column_stack(correctorsList)

            worldpFineIndices = np.dot(finepBasis, iElementWorldCoarse*NCoarseElement) + elementpIndexMapFine
            basis[np.ix_(worldpFineIndices, worldpIndices)] = world.localBasis

        AGlob = fem.assemblePatchMatrix(NWorldFine, world.ALocFine, aWorld)

        alpha = np.random.rand(world.NpCoarse)
        vH  = np.dot(basis, alpha)
        QvH = np.dot(correctors, alpha)

        # Check norm inequality
        self.assertTrue(np.dot(QvH.T, AGlob*QvH) <= np.dot(vH.T, AGlob*vH))

        # Check that correctors are really fine functions
        self.assertTrue(np.isclose(np.linalg.norm(IWorld*correctors, ord=np.inf), 0))

        v = np.random.rand(world.NpFine, world.NpCoarse)
        v[util.boundarypIndexMap(NWorldFine)] = 0
        # The chosen interpolation operator doesn't ruin the boundary conditions.
        vf = v-np.dot(basis, IWorld*v)
        vf = vf/np.sqrt(np.sum(vf*(AGlob*vf), axis=0))
        # Check orthogonality
        self.assertTrue(np.isclose(np.linalg.norm(np.dot(vf.T, AGlob*(correctors - basis)), ord=np.inf), 0))
コード例 #7
0
ファイル: lod_wave.py プロジェクト: ollema/lod-wave
    def assembleBasisCorrectors(self):
        '''
        Constructs {Q\lambda_x}_x by the sum Q\lambda_x = \sum_T Q_T\lambda_x
        '''

        if self.basis_correctors is not None:
            return self.basis_correctors

        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.convertpCoordIndexToLinearIndex(
                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)

        basis_correctors = sparse.csc_matrix((data, (rows, cols)),
                                             shape=(NpFine, NpCoarse))

        self.basis_correctors = basis_correctors
        return basis_correctors
コード例 #8
0
ファイル: lod_node.py プロジェクト: ollema/lod-wave
    def compute_localized_node_correction(self, b_patch, a_patch, IPatch,
                                          prev_fs_sol, node_index):
        '''Compute the fine correctors over the node based patch.

        Compute the correctors, for all z \in V^f(U(\omega_{x,k})):

        a(\phi_x, z) + \tau b(\phi_x, z) = a(\lambda_x, z) + \tau b(\lambda_x, z)
        '''

        world = self.world
        NCoarseElement = world.NCoarseElement
        NPatchCoarse = self.NPatchCoarse
        iPatchWorldCoarse = self.iPatchWorldCoarse

        NPatchFine = NPatchCoarse * NCoarseElement
        NtFine = np.prod(NPatchFine)
        NpFine = np.prod(NPatchFine + 1)

        iPatchWorldFine = iPatchWorldCoarse * NCoarseElement
        patchpIndexMap = util.lowerLeftpIndexMap(NPatchFine, world.NWorldFine)
        patchpStartIndex = util.convertpCoordIndexToLinearIndex(
            world.NWorldFine, iPatchWorldFine)

        patch_indices = patchpStartIndex + patchpIndexMap

        b_patch = b_patch.aFine
        a_patch = a_patch.aFine

        assert (np.size(b_patch) == NtFine)
        S_patch = fem.assemblePatchMatrix(NPatchFine, world.ALocFine, b_patch)
        K_patch = fem.assemblePatchMatrix(NPatchFine, world.ALocFine, a_patch)
        bPatchFull = np.zeros(NpFine)

        if prev_fs_sol is not None:
            if type(prev_fs_sol) is not np.ndarray:
                bPatchFull += K_patch * prev_fs_sol.toarray(
                )[:, node_index][patch_indices]
                #bPatchFull += prev_fs_sol.toarray()[:, node_index][patch_indices].T * K_patch
            else:
                bPatchFull += K_patch * prev_fs_sol[patch_indices]
                #bPatchFull += prev_fs_sol[patch_indices].T * K_patch
        fs_patch_solution = ritzProjectionToFinePatchWithGivenSaddleSolver(
            world, self.iPatchWorldCoarse, NPatchCoarse, S_patch + K_patch,
            [bPatchFull], IPatch, self.saddleSolver)

        fs_solution = np.zeros(world.NpFine)
        fs_solution[patch_indices] += fs_patch_solution[0]

        return fs_solution
コード例 #9
0
    def test_computeSingleT(self):
        NWorldCoarse = np.array([4, 5, 6])
        NCoarseElement = np.array([5, 2, 3])
        world = World(NWorldCoarse, NCoarseElement)
        d = np.size(NWorldCoarse)
        
        k = 1
        iElementWorldCoarse = np.array([2, 1, 2])
        TInd = util.convertpCoordIndexToLinearIndex(NWorldCoarse, iElementWorldCoarse)
        patch = Patch(world, k, TInd)

        IPatch = interp.L2ProjectionPatchMatrix(patch)
        
        NtPatch = patch.NtFine

        aPatch = np.ones(NtPatch)
        basisCorrectorsList = lod.computeBasisCorrectors(patch, IPatch, aPatch)

        correctorSum = reduce(np.add, basisCorrectorsList)
        self.assertTrue(np.allclose(correctorSum, 0))

        csi = lod.computeBasisCoarseQuantities(patch, basisCorrectorsList, aPatch)
        # Test that the matrices have the constants in their null space
        #self.assertTrue(np.allclose(np.sum(ec.csi.LTPrimeij, axis=1), 0))
        #self.assertTrue(np.allclose(np.sum(ec.csi.LTPrimeij, axis=2), 0))

        self.assertTrue(np.allclose(np.sum(csi.Kij, axis=0), 0))
        self.assertTrue(np.allclose(np.sum(csi.Kij, axis=1), 0))
        self.assertTrue(np.allclose(np.sum(csi.Kmsij, axis=0), 0))
        self.assertTrue(np.allclose(np.sum(csi.Kmsij, axis=1), 0))

        # I had difficulties come up with test cases here. This test
        # verifies that most "energy" is in the element T.
        elementTIndex = util.convertpCoordIndexToLinearIndex(patch.NPatchCoarse-1, patch.iElementPatchCoarse)
        self.assertTrue(np.all(csi.muTPrime[elementTIndex] >= csi.muTPrime))
        self.assertTrue(not np.all(csi.muTPrime[elementTIndex+1] >= csi.muTPrime))
コード例 #10
0
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
コード例 #11
0
ファイル: pg_pert.py プロジェクト: daveb-dev/MasterthesisLOD
    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.convertpCoordIndexToLinearIndex(
                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
コード例 #12
0
    def test_testCsi_Kmsij(self):
        NWorldCoarse = np.array([4, 5, 6])
        NCoarseElement = np.array([5, 2, 3])
        world = World(NWorldCoarse, NCoarseElement)
        d = np.size(NWorldCoarse)
        
        k = 1
        iElementWorldCoarse = np.array([2, 1, 2])
        TInd = util.convertpCoordIndexToLinearIndex(NWorldCoarse, iElementWorldCoarse)
        patch = Patch(world, k, TInd)
        
        IPatch = interp.L2ProjectionPatchMatrix(patch)
        
        NtPatch = patch.NtFine
        np.random.seed(1)
        aPatch = np.random.rand(NtPatch)
        basisCorrectorsList = lod.computeBasisCorrectors(patch, IPatch, aPatch)
        csi = lod.computeBasisCoarseQuantities(patch, basisCorrectorsList, aPatch)

        TFinetIndexMap   = util.extractElementFine(patch.NPatchCoarse,
                                                   NCoarseElement,
                                                   patch.iElementPatchCoarse,
                                                   extractElements=True)
        TFinepIndexMap   = util.extractElementFine(patch.NPatchCoarse,
                                                   NCoarseElement,
                                                   patch.iElementPatchCoarse,
                                                   extractElements=False)
        TCoarsepIndexMap   = util.extractElementFine(patch.NPatchCoarse,
                                                     np.ones_like(NCoarseElement),
                                                     patch.iElementPatchCoarse,
                                                     extractElements=False)

        APatchFine      = fem.assemblePatchMatrix(patch.NPatchFine, world.ALocFine, aPatch)
        AElementFine    = fem.assemblePatchMatrix(NCoarseElement, world.ALocFine, aPatch[TFinetIndexMap])
        basisPatch      = fem.assembleProlongationMatrix(patch.NPatchCoarse, NCoarseElement)
        correctorsPatch = np.column_stack(basisCorrectorsList)

        localBasis = world.localBasis

        KmsijShouldBe = -basisPatch.T*(APatchFine*(correctorsPatch))
        KmsijShouldBe[TCoarsepIndexMap,:] += np.dot(localBasis.T, AElementFine*localBasis)
        
        self.assertTrue(np.isclose(np.max(np.abs(csi.Kmsij-KmsijShouldBe)), 0))
コード例 #13
0
def computeErrorIndicatorCoarse_helmholtz(patch, muTPrime, aPatchOld,
                                          aPatchNew):
    ''' Compute the coarse error idicator E(T) with explicit value of AOld and ANew.

    This requires muTPrime from CSI and the new and old coefficient.
    '''

    while callable(muTPrime):
        muTPrime = muTPrime()

    while callable(aPatchOld):
        aPatchOld = aPatchOld()

    while callable(aPatchNew):
        aPatchNew = aPatchNew()

    aOld = aPatchOld
    aNew = aPatchNew

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

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

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

    TPrimeIndices = np.add.outer(TPrimeFinetStartIndices, TPrimeFinetIndexMap)
    aTPrime = aNew[TPrimeIndices]
    aOldTPrime = aOld[TPrimeIndices]

    deltaMaxTPrime = np.max(np.abs(aTPrime - aOldTPrime), axis=1)

    epsilonTSquare = np.sum((deltaMaxTPrime**2) * muTPrime)

    return np.sqrt(epsilonTSquare)
コード例 #14
0
ファイル: lod_node.py プロジェクト: ollema/lod-wave
    def compute_localized_basis_node(self, b_patch, a_patch, IPatch, basis,
                                     node_index):
        '''
        Description
        '''

        world = self.world
        NCoarseElement = world.NCoarseElement
        NPatchCoarse = self.NPatchCoarse
        iPatchWorldCoarse = self.iPatchWorldCoarse

        NPatchFine = NPatchCoarse * NCoarseElement
        NtFine = np.prod(NPatchFine)
        NpFine = np.prod(NPatchFine + 1)

        iPatchWorldFine = iPatchWorldCoarse * NCoarseElement
        patchpIndexMap = util.lowerLeftpIndexMap(NPatchFine, world.NWorldFine)
        patchpStartIndex = util.convertpCoordIndexToLinearIndex(
            world.NWorldFine, iPatchWorldFine)

        patch_indices = patchpStartIndex + patchpIndexMap

        b_patch = b_patch.aFine
        a_patch = a_patch.aFine

        assert (np.size(b_patch) == NtFine)
        S_patch = fem.assemblePatchMatrix(NPatchFine, world.ALocFine, b_patch)
        K_patch = fem.assemblePatchMatrix(NPatchFine, world.ALocFine, a_patch)
        bPatchFull = np.zeros(NpFine)

        bPatchFull += K_patch * basis.toarray()[:, node_index][patch_indices]
        bPatchFull += S_patch * basis.toarray()[:, node_index][patch_indices]

        ms_basis_patch_solution = ritzProjectionToFinePatchWithGivenSaddleSolver(
            world, self.iPatchWorldCoarse, NPatchCoarse, S_patch + K_patch,
            [bPatchFull], IPatch, self.saddleSolver)

        ms_basis_solution = np.zeros(world.NpFine)
        ms_basis_solution[patch_indices] += ms_basis_patch_solution[0]

        return ms_basis_solution
コード例 #15
0
ファイル: lod_node.py プロジェクト: ollema/lod-wave
    def compute_rb_node_correction_test(self, b_patch, a_patch, IPatch,
                                        prev_fs_sol, V):

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

        NPatchFine = NPatchCoarse * NCoarseElement
        NtFine = np.prod(NPatchFine)
        NpCoarse = np.prod(NPatchCoarse + 1)
        NpFine = np.prod(NPatchFine + 1)
        iPatchWorldCoarse = self.iPatchWorldCoarse

        iPatchWorldFine = iPatchWorldCoarse * NCoarseElement
        patchpIndexMap = util.lowerLeftpIndexMap(NPatchFine, world.NWorldFine)
        patchpStartIndex = util.convertpCoordIndexToLinearIndex(
            world.NWorldFine, iPatchWorldFine)

        patch_indices = patchpStartIndex + patchpIndexMap

        b_patch = b_patch.aFine
        a_patch = a_patch.aFine

        assert (np.size(b_patch) == NtFine)

        SPatchFull = fem.assemblePatchMatrix(NPatchFine, world.ALocFine,
                                             b_patch)
        KPatchFull = fem.assemblePatchMatrix(NPatchFine, world.ALocFine,
                                             a_patch)
        bPatchFullList = []
        bPatchFull = np.zeros(len((V.todense())))
        V = V[:, patch_indices]
        bPatchFull += prev_fs_sol[patch_indices].T * KPatchFull * V.T
        bPatchFullList.append(bPatchFull)
        SPatchFull = V * SPatchFull * V.T
        KPatchFull = V * KPatchFull * V.T

        correctorsList = linalg.linSolve(KPatchFull + SPatchFull, bPatchFull.T)

        return correctorsList
コード例 #16
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)
コード例 #17
0
def computeBasisCoarseQuantities_helmholtz(patch, correctorsList, aPatch,
                                           kPatch, k2Patch):
    ''' Compute the coarse quantities for the basis and its correctors

    Compute the tensors (T is implicit by the patch definition) and
    return them in a CoarseScaleInformation object:

       Kij   = (A \nabla lambda_j, \nabla lambda_i)_{T}
       KmsTij = (A \nabla (lambda_j - corrector_j), \nabla lambda_i)_{U_k(T)}
       Mij = (k^2n lambda_j, lambda_i)_{T}
       Mmsij = (k^2n (lambda_j - corrector_j), lambda_i)_{U_k(T)}
       Bdij = (k lambda_j, lambda_i)_{\partial T \cap \partial \Omega}
       Bdmsij = (k (lambda_j - corrector_j), lambda_i)_{\partial T \cap \partial \Omega}
       muTT'  = max_{\alpha_j} || \alpha_j (\chi_T lambda_j - corrector_j) ||^2_T' / || \alpha_j lambda_j ||^2_T

       Auxiliary quantities are computed, but not saved
    '''

    lambdasList = list(patch.world.localBasis.T)

    NPatchCoarse = patch.NPatchCoarse
    NTPrime = np.prod(NPatchCoarse)
    NpPatchCoarse = np.prod(NPatchCoarse + 1)
    numLambdas = len(lambdasList)

    TInd = util.convertpCoordIndexToLinearIndex(patch.NPatchCoarse - 1,
                                                patch.iElementPatchCoarse)

    Kmsij = np.zeros((NpPatchCoarse, numLambdas), dtype='complex128')
    Mmsij = np.zeros((NpPatchCoarse, numLambdas), dtype='complex128')
    Bdmsij = np.zeros((NpPatchCoarse, numLambdas), dtype='complex128')
    LTPrimeij = np.zeros((NTPrime, numLambdas, numLambdas), dtype='complex128')
    Kij = np.zeros((numLambdas, numLambdas), dtype='complex128')
    Mij = np.zeros((numLambdas, numLambdas), dtype='complex128')
    Bdij = np.zeros((numLambdas, numLambdas), dtype='complex128')
    L2ij = np.zeros((numLambdas, numLambdas), dtype='complex128')

    def accumulate(TPrimeInd, TPrimei, P, Q, KTPrime, _KTPrimeij, MTPrime,
                   BdTPrime, _MTPrimeij, _BdTPrimeij, L2TPrime, CTPrimeij,
                   BTPrimeij):
        if TPrimeInd == TInd:
            Kij[:] = np.dot(P.T, KTPrime * P)
            Mij[:] = np.dot(P.T, MTPrime * P)
            Bdij[:] = np.dot(P.T, BdTPrime * P)
            L2ij[:] = np.dot(P.T, L2TPrime * P)
            LTPrimeij[TPrimeInd] = CTPrimeij \
                                   - BTPrimeij \
                                   - BTPrimeij.T \
                                   + L2ij

            Kmsij[TPrimei, :] += Kij - _KTPrimeij
            Mmsij[TPrimei, :] += Mij - _MTPrimeij
            Bdmsij[TPrimei, :] += Bdij - _BdTPrimeij
        else:
            LTPrimeij[TPrimeInd] = CTPrimeij
            Kmsij[TPrimei, :] += -_KTPrimeij
            Mmsij[TPrimei, :] += -_MTPrimeij
            Bdmsij[TPrimei, :] += -_BdTPrimeij

    performTPrimeLoop_helmholtz(patch, lambdasList, correctorsList, aPatch,
                                kPatch, k2Patch, accumulate)

    muTPrime = np.zeros(NTPrime, dtype='complex128')
    cutRows = 0
    while np.linalg.cond(L2ij[cutRows:, cutRows:]) > 1e8:
        cutRows = cutRows + 1
    for TPrimeInd in np.arange(NTPrime):
        # Solve eigenvalue problem LTPrimeij x = mu_TPrime Mij x
        eigenvalues = scipy.linalg.eigvals(
            LTPrimeij[TPrimeInd][cutRows:, cutRows:], L2ij[cutRows:, cutRows:])
        muTPrime[TPrimeInd] = np.max(np.real(eigenvalues))

    return CoarseScaleInformation_helmholtz(Kij, Kmsij, muTPrime, Mij, Mmsij,
                                            Bdij, Bdmsij)
コード例 #18
0
    def test_computeCoarseErrorIndicatorFlux(self):
        NWorldCoarse = np.array([7, 7], dtype='int64')
        NCoarseElement = np.array([10, 10], dtype='int64')
        NWorldFine = NWorldCoarse * NCoarseElement
        NpWorldFine = np.prod(NWorldFine + 1)
        NpWorldCoarse = np.prod(NWorldCoarse + 1)
        NtWorldFine = np.prod(NWorldCoarse * NCoarseElement)
        NtWorldCoarse = np.prod(NWorldCoarse)

        np.random.seed(0)

        world = World(NWorldCoarse, NCoarseElement)
        d = np.size(NWorldCoarse)
        aBase = np.exp(np.random.rand(NtWorldFine))
        k = np.max(NWorldCoarse)
        iElementWorldCoarse = np.array([3, 3])

        rCoarseFirst = 1 + 3 * np.random.rand(NtWorldCoarse)
        coefFirst = coef.CoefficientCoarseFactor(NWorldCoarse, NCoarseElement,
                                                 aBase, rCoarseFirst)
        IPatchGenerator = lambda i, N: interp.L2ProjectionPatchMatrix(
            i, N, NWorldCoarse, NCoarseElement)
        ec = lod_flux.CoarseBasisElementCorrectorFlux(world, k,
                                                      iElementWorldCoarse,
                                                      IPatchGenerator)
        ec.computeCorrectors(coefFirst)
        ec.computeCoarseQuantities()

        # If both rCoarseFirst and rCoarseSecond are equal, the error indicator should be zero
        rCoarseSecond = np.array(rCoarseFirst)
        self.assertTrue(
            np.isclose(ec.computeCoarseErrorIndicatorFlux(rCoarseSecond), 0))

        coefSecond = coef.CoefficientCoarseFactor(NWorldCoarse, NCoarseElement,
                                                  aBase, rCoarseSecond)
        self.assertTrue(np.isclose(ec.computeErrorIndicatorFine(coefSecond),
                                   0))

        # If rCoarseSecond is not rCoarseFirst, the error indicator should not be zero
        rCoarseSecond = 2 * np.array(rCoarseFirst)
        self.assertTrue(
            ec.computeCoarseErrorIndicatorFlux(rCoarseSecond) >= 0.1)

        coefSecond = coef.CoefficientCoarseFactor(NWorldCoarse, NCoarseElement,
                                                  aBase, rCoarseSecond)
        self.assertTrue(ec.computeErrorIndicatorFine(coefSecond) >= 0.1)

        # Fine should be smaller than coarse estimate
        self.assertTrue(
            ec.computeErrorIndicatorFine(coefSecond) <
            ec.computeCoarseErrorIndicatorFlux(rCoarseSecond))

        # If rCoarseSecond is different in the element itself, the error
        # indicator should be large
        elementCoarseIndex = util.convertpCoordIndexToLinearIndex(
            NWorldCoarse - 1, iElementWorldCoarse)
        rCoarseSecond = np.array(rCoarseFirst)
        rCoarseSecond[elementCoarseIndex] *= 2
        saveForNextTest = ec.computeCoarseErrorIndicatorFlux(rCoarseSecond)
        self.assertTrue(saveForNextTest >= 0.1)

        coefSecond = coef.CoefficientCoarseFactor(NWorldCoarse, NCoarseElement,
                                                  aBase, rCoarseSecond)
        fineResult = ec.computeErrorIndicatorFine(coefSecond)
        self.assertTrue(fineResult >= 0.1)
        self.assertTrue(
            ec.computeErrorIndicatorFine(coefSecond) <
            ec.computeCoarseErrorIndicatorFlux(rCoarseSecond))

        # A difference in the perifery should be smaller than in the center
        rCoarseSecond = np.array(rCoarseFirst)
        rCoarseSecond[0] *= 2
        self.assertTrue(
            saveForNextTest > ec.computeCoarseErrorIndicatorFlux(rCoarseSecond)
        )

        # Again, but closer
        rCoarseSecond = np.array(rCoarseFirst)
        rCoarseSecond[elementCoarseIndex - 1] *= 2
        self.assertTrue(
            saveForNextTest > ec.computeCoarseErrorIndicatorFlux(rCoarseSecond)
        )
コード例 #19
0
def computeErrorIndicatorFineMultiple(patch,
                                      correctorsList,
                                      aRefList,
                                      mu,
                                      aPatchNew=None):
    ''' Compute the fine error indicator e(T) for given vector mu.

    This requires reference coefficients (already localized) and their correctors. New coefficient is optional, otherwise
    assumed to be weighted sum of mu and reference coefficients.
    '''

    while callable(aPatchNew):
        aPatchNew = aPatchNew()

    if aRefList[0].ndim != 1:
        NotImplementedError("matrix-valued coefficient not yet supported")

    lambdasList = list(patch.world.localBasis.T)

    NPatchCoarse = patch.NPatchCoarse
    world = patch.world
    NCoarseElement = world.NCoarseElement
    NPatchFine = NPatchCoarse * NCoarseElement

    nref = len(aRefList)
    a = aPatchNew

    ALocFine = world.ALocFine
    P = np.column_stack(lambdasList)

    TFinetIndexMap = util.lowerLeftpIndexMap(NCoarseElement - 1,
                                             NPatchFine - 1)
    iElementPatchFine = patch.iElementPatchCoarse * NCoarseElement
    TFinetStartIndex = util.convertpCoordIndexToLinearIndex(
        NPatchFine - 1, iElementPatchFine)
    TFinepIndexMap = util.lowerLeftpIndexMap(NCoarseElement, NPatchFine)
    TFinepStartIndex = util.convertpCoordIndexToLinearIndex(
        NPatchFine, iElementPatchFine)

    A = np.zeros_like(world.ALocCoarse)
    aBar = np.einsum('i, ij->j', mu, aRefList)
    if aPatchNew is None:
        a = aBar
    else:
        a = aPatchNew
        bTcoeff = np.sqrt(a) * (1 - aBar / a)
        bT = bTcoeff[TFinetStartIndex + TFinetIndexMap]
        TNorm = fem.assemblePatchMatrix(NCoarseElement, ALocFine, bT**2)

    nnz = np.where(mu != 0)[0]

    def addtoA(A, kk):
        ii = kk[0]
        jj = kk[1]
        bij = (mu[ii] * np.sqrt(a) *
               (1 - aRefList[ii] / a)) * (mu[jj] * np.sqrt(a) *
                                          (1 - aRefList[jj] / a))
        PatchNorm = fem.assemblePatchMatrix(NPatchFine, ALocFine, bij)
        Q1 = np.column_stack(correctorsList[ii])
        Q2 = np.column_stack(correctorsList[jj])
        A += np.dot(Q1.T, PatchNorm * Q2)
        if aPatchNew is not None:
            bii = mu[ii] * np.sqrt(a) * (1 - aRefList[ii] / a)
            bjj = mu[jj] * np.sqrt(a) * (1 - aRefList[jj] / a)
            bTii = bT * bii[TFinetStartIndex + TFinetIndexMap]
            bTjj = bT * bjj[TFinetStartIndex + TFinetIndexMap]
            TNormPQ = fem.assemblePatchMatrix(NCoarseElement, ALocFine, bTjj)
            TNormQP = fem.assemblePatchMatrix(NCoarseElement, ALocFine, bTii)
            QT1 = Q1[TFinepStartIndex + TFinepIndexMap, :]
            QT2 = Q2[TFinepStartIndex + TFinepIndexMap, :]
            A -= np.dot(P.T, TNormPQ * QT2)
            A -= np.dot(QT1.T, TNormQP * P)

    assembleA = lambda kk: addtoA(A, kk)
    import itertools
    list(map(assembleA, itertools.product(nnz, repeat=2)))

    if aPatchNew is not None:
        A += np.dot(P.T, TNorm * P)

    BNorm = fem.assemblePatchMatrix(NCoarseElement, ALocFine,
                                    a[TFinetStartIndex + TFinetIndexMap])
    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)