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