Esempio n. 1
0
    def __init__(self, *args):

        args = list(args)
        self.bc_mats = []
        if isinstance(args[-1], (TPMatrix, SpectralMatrix)):
            bc_mats = extract_bc_matrices([args])
            self.tpmats = args
            self.bc_mats = bc_mats

        assert len(args) in (3, 6)

        S, A, B = args[:3]
        M = {d.get_key(): d for d in (S, A, B)}
        self.S = M['SSBSBmat']
        self.A = M['ASBSBmat']
        self.B = M['BSBSBmat']

        if len(args) == 3:
            self.a0 = a0 = np.atleast_1d(self.S.scale).item()
            self.alfa = alfa = self.A.scale
            self.beta = beta = self.B.scale
            if isinstance(self.S, TPMatrix):
                self.S = self.S.pmat
                self.A = self.A.pmat
                self.B = self.B.pmat
                self.alfa *= self.A.scale
                self.beta *= self.B.scale
        elif len(args) == 6:
            self.a0 = a0 = args[3]
            self.alfa = alfa = args[4]
            self.beta = beta = args[5]

        S, A, B = self.S, self.A, self.B
        self.axis = S.axis
        T = S.tensorproductspace
        if T is None:
            shape = [S[0].shape]
        else:
            shape = list(T.shape(True))
        sii, siu, siuu = S[0], S[2], S[4]
        ail, aii, aiu = A[-2], A[0], A[2]
        bill, bil, bii, biu, biuu = B[-4], B[-2], B[0], B[2], B[4]
        M = sii[::2].shape[0]
        shape[S.axis] = M
        ss = copy(shape)
        ss.insert(0, 2)
        self.u0 = np.zeros(ss)
        self.u1 = np.zeros(ss)
        self.u2 = np.zeros(ss)
        self.l0 = np.zeros(ss)
        self.l1 = np.zeros(ss)
        self.ak = np.zeros(ss)
        self.bk = np.zeros(ss)

        self.LU_Biharmonic(a0, alfa, beta, sii, siu, siuu, ail, aii, aiu, bill,
                           bil, bii, biu, biuu, self.u0, self.u1, self.u2,
                           self.l0, self.l1, self.axis)
        self.Biharmonic_factor_pr(self.ak, self.bk, self.l0, self.l1,
                                  self.axis)
Esempio n. 2
0
    def __init__(self, *args):

        args = list(args)
        self.bc_mats = []
        if isinstance(args[-1], (TPMatrix, SpectralMatrix)):
            bc_mats = extract_bc_matrices([args])
            self.tpmats = args
            self.bc_mats = bc_mats

        assert len(args) in (2, 4)
        A, B = args[:2]
        M = {d.get_key(): d for d in (A, B)}
        self.A = A = M.get('ASDSDmat', M.get('ASNSNmat'))
        self.B = B = M.get('BSDSDmat', M.get('BSNSNmat'))

        if len(args) == 2:
            self.alfa = self.A.scale
            self.beta = self.B.scale
            if isinstance(self.A, TPMatrix):
                self.A = self.A.pmat
                self.B = self.B.pmat
                self.alfa *= self.A.scale
                self.beta *= self.B.scale
        elif len(args) == 4:
            self.alfa = args[2]
            self.beta = args[3]

        A, B = self.A, self.B
        B[2] = np.broadcast_to(B[2], A[2].shape)
        B[-2] = np.broadcast_to(B[-2], A[2].shape)
        v = A.testfunction[0]
        neumann = self.neumann = self.A.testfunction[0].boundary_condition() == 'Neumann'
        self.axis = A.axis
        shape = [1]
        T = A.tensorproductspace
        if T is not None:
            shape = list(T.shape(True))
            shape[A.axis] = 1
        self.alfa = np.atleast_1d(self.alfa)
        self.beta = np.atleast_1d(self.beta)
        if not self.alfa.shape == shape:
            self.alfa = np.broadcast_to(self.alfa, shape).copy()
        if not self.beta.shape == shape:
            self.beta = np.broadcast_to(self.beta, shape).copy()

        shape[self.axis] = A.shape[0] + 2
        self.u0 = np.zeros(shape)     # Diagonal entries of U
        self.u1 = np.zeros(shape)     # Diagonal+2 entries of U
        self.u2 = np.zeros(shape)     # Diagonal+4 entries of U
        self.L = np.zeros(shape)      # The single nonzero row of L
        self.LU_Helmholtz(A, B, self.alfa, self.beta, neumann, self.u0,
                          self.u1, self.u2, self.L, self.axis)
Esempio n. 3
0
    def __init__(self, A, test):
        assert isinstance(A, (SparseMatrix, list))
        self.s = test.slice()
        self.bc_mats = []
        if isinstance(A, list):
            bc_mats = extract_bc_matrices([A])
            self.A = np.sum(np.array(A, dtype=object))
            self.bc_mats = bc_mats
        else:
            self.A = A

        self.test = test
        assert self.A.shape[0] == self.A.shape[1]
Esempio n. 4
0
 def __init__(self, mats):
     assert isinstance(mats, list)
     naxes = set()
     for tpmat in mats:
         if not tpmat._issimplified:
             tpmat.simplify_diagonal_matrices()
         naxes.update(tpmat.naxes)
     assert len(naxes) == 1
     self.naxes = naxes.pop()
     bc_mats = extract_bc_matrices([mats])
     self.mats = mats
     self.bc_mats = bc_mats
     # For time-dependent solver, store all generated matrices and reuse
     # This takes a lot of memory, so for now it's only implemented for 2D
     self.MM = None
Esempio n. 5
0
    def __init__(self, tpmats, fixed_gauge=None):
        bc_mats = extract_bc_matrices([tpmats])
        self.tpmats = tpmats
        self.bc_mats = bc_mats
        self._lu = None
        m = tpmats[0]
        self.T = T = m.space  # test space
        ndim = T.dimensions
        assert ndim == 3
        assert np.atleast_1d(
            m.scale).size == 1, "Use level = 2 with :func:`.inner`"

        A0 = m.mats[0].diags('csc')
        A1 = m.mats[1].diags('csc')
        A2 = m.mats[2].diags('csc')
        M0 = scp.kron(scp.kron(A0, A1, 'csc'), A2, 'csc')
        M0 *= np.atleast_1d(m.scale).item()
        for m in tpmats[1:]:
            A0 = m.mats[0].diags('csc')
            A1 = m.mats[1].diags('csc')
            A2 = m.mats[2].diags('csc')
            M1 = scp.kron(scp.kron(A0, A1, 'csc'), A2, 'csc')
            assert np.atleast_1d(
                m.scale).size == 1, "Use level = 2 with :func:`.inner`"
            M1 *= np.atleast_1d(m.scale).item()
            M0 = M0 + M1

        # Check if we need to fix gauge. This is required if we are solving
        # a pure Neumann Poisson problem.
        if fixed_gauge:
            # Ident first row
            z0 = M0[0].nonzero()
            if len(z0[0]) == 0 or z0[1][0] > 0:
                M0 = M0.tolil()
                zerorow = M0[0].nonzero()[1]
                M0[(0, zerorow)] = 0
                M0[0, 0] = 1
                M0 = M0.tocsc()
        self.M = M0
Esempio n. 6
0
    def __init__(self, *args):

        args = list(args)
        self.bc_mats = []
        if isinstance(args[-1], (TPMatrix, SpectralMatrix)):
            bc_mats = extract_bc_matrices([args])
            self.tpmats = args
            self.bc_mats = bc_mats

        #assert len(args) in (3, 6)
        S, A, B = args[:3]
        M = {d.get_key(): d for d in (S, A, B)}
        self.S = M['SSBSBmat']
        self.A = M['ASBSBmat']
        self.B = M['BSBSBmat']

        if len(args) == 3:
            S_scale = self.S.scale
            A_scale = self.A.scale
            B_scale = self.B.scale
            if isinstance(self.S, TPMatrix):
                S = self.S.mats[self.A.naxes[0]]
                A = self.A.pmat
                B = self.B.pmat
                A_scale *= A.scale
                B_scale *= B.scale
                S_scale *= S.scale
        elif len(args) == 6:
            S_scale = np.asscalar(args[3])
            A_scale = args[4]
            B_scale = args[5]

        v = S.testfunction[0]
        self.s = v.sl[v.slice()]
        self.bc = v.bc
        if np.ndim(B_scale) > 1:
            shape = list(B_scale.shape)
            self.axis = S.axis
            shape[S.axis] = v.N
            self.d0 = np.zeros(shape)
            self.d1 = np.zeros(shape)
            self.d2 = np.zeros(shape)
            S0 = v.broadcast_to_ndims(np.atleast_1d(S[0]))
            A0 = v.broadcast_to_ndims(A[0])
            B0 = v.broadcast_to_ndims(B[0])
            A2 = v.broadcast_to_ndims(A[2])
            B2 = v.broadcast_to_ndims(B[2])
            B4 = v.broadcast_to_ndims(B[4])
            ss = [slice(None)] * self.d0.ndim
            ss[S.axis] = slice(0, A[0].shape[0])
            self.d0[tuple(ss)] = S0 * S_scale + A0 * A_scale + B0 * B_scale
            ss[S.axis] = slice(0, A[2].shape[0])
            self.d1[tuple(ss)] = A2 * A_scale + B2 * B_scale
            ss[S.axis] = slice(0, B[4].shape[0])
            self.d2[tuple(ss)] = B4 * B_scale
            self.PDMA_SymLU_VC(self.d0, self.d1, self.d2, S.axis)

        else:
            self.d0 = S[0] * S_scale + A[0] * A_scale + B[0] * B_scale
            self.d1 = A[2] * A_scale + B[2] * B_scale
            self.d2 = B[4] * B_scale
            self.axis = 0
            la.PDMA_SymLU(self.d0, self.d1, self.d2)
Esempio n. 7
0
    def __init__(self, *args, **kwargs):
        args = list(args)
        self.bc_mats = []
        if isinstance(args[-1], (TPMatrix, SpectralMatrix)):
            bc_mats = extract_bc_matrices([args])
            self.tpmats = args
            self.bc_mats = bc_mats

        A, B = args[:2]
        M = {d.get_key(): d for d in (A, B)}
        self.A = A = M.get('ASDSDmat', M.get('ASNSNmat'))
        self.B = B = M.get('BSDSDmat', M.get('BSNSNmat'))
        naxes = B.naxes[0] if isinstance(B, TPMatrix) else B.axis
        if len(args) == 2:
            A_scale = self.A.scale
            B_scale = self.B.scale
            if isinstance(self.A, TPMatrix):
                A = self.A.mats[naxes]
                B = self.B.mats[naxes]
                A_scale *= A.scale
                B_scale *= B.scale
        else:
            A_scale = args[2]
            B_scale = args[3]

        v = A.testfunction[0]
        self.s = v.sl[v.slice()]
        neumann = self.neumann = v.boundary_condition() == 'Neumann'
        if not neumann:
            self.bc = v.bc
            self.scaled = v.is_scaled()

        self.axis = A.axis
        shape = [1]
        T = A.tensorproductspace
        if T is not None:
            shape = list(T.shape(True))
            shape[A.axis] = 1

        if np.ndim(B_scale) > 1:
            if len(shape) == 2:
                if neumann and B_scale[0, 0] == 0:
                    B_scale[0, 0] = 1.

            elif len(shape) == 3:
                if neumann and B_scale[0, 0, 0] == 0:
                    B_scale[0, 0, 0] = 1.

            A[0] = np.atleast_1d(A[0])
            if A[0].shape[0] == 1:
                A[0] = np.ones(A.shape[0]) * A[0]
            A0 = v.broadcast_to_ndims(A[0])
            B0 = v.broadcast_to_ndims(B[0])
            B2 = v.broadcast_to_ndims(B[2])
            shape[A.axis] = v.N
            self.d0 = np.zeros(shape)
            self.d1 = np.zeros(shape)
            ss = [slice(None)] * self.d0.ndim
            ss[self.axis] = slice(0, A.shape[0])
            self.d0[tuple(ss)] = A0 * A_scale + B0 * B_scale
            ss[self.axis] = slice(0, A.shape[0] - 2)
            self.d1[tuple(ss)] = B2 * B_scale
            self.L = np.zeros_like(self.d0)
            self.TDMA_SymLU_VC(self.d0, self.d1, self.L, self.axis)

        else:
            self.d0 = A[0] * A_scale + B[0] * B_scale
            self.d1 = B[2] * B_scale
            self.L = np.zeros_like(self.d1)
            self.bc = A.testfunction[0].bc
            self.axis = 0
            self.TDMA_SymLU(self.d0, self.d1, self.L)