def get_smamin_rearrangement(N,PrP,Mc,Bc): from smamin_utils import col_columns_atend from scipy.io import loadmat, savemat # get the indices of the B2-part B2Inds = get_B2_bubbleinds(N, PrP.V, PrP.mesh) # the B2 inds wrt to inner nodes # this gives a masked array of boolean type B2BoolInv = np.in1d(np.arange(PrP.V.dim())[PrP.invinds], B2Inds) # this as indices B2BI = np.arange(len(B2BoolInv), dtype=np.int32)[B2BoolInv] dname = '%sSmeMcBc' % N try: SmDic = loadmat(dname) except IOError: print 'Computing the B2 indices...' # get the indices of the B2-part B2Inds = get_B2_bubbleinds(N, PrP.V, PrP.mesh) # the B2 inds wrt to inner nodes # this gives a masked array of boolean type B2BoolInv = np.in1d(np.arange(PrP.V.dim())[PrP.invinds], B2Inds) # this as indices B2BI = np.arange(len(B2BoolInv), dtype=np.int32)[B2BoolInv] # Reorder the matrices for smart min ext... # ...the columns print 'Rearranging the matrices...' # Reorder the matrices for smart min ext... # ...the columns MSmeC = col_columns_atend(Mc, B2BI) BSme = col_columns_atend(Bc, B2BI) # ...and the lines MSmeCL = col_columns_atend(MSmeC.T, B2BI) print 'done' savemat(dname, { 'MSmeCL': MSmeCL, 'BSme':BSme, 'B2Inds':B2Inds, 'B2BoolInv':B2BoolInv, 'B2BI':B2BI} ) SmDic = loadmat(dname) MSmeCL = SmDic['MSmeCL'] BSme = SmDic['BSme'] B2Inds = SmDic['B2Inds'] B2BoolInv = SmDic['B2BoolInv']>0 B2BoolInv = B2BoolInv.flatten() B2BI = SmDic['B2BI'] return MSmeCL, BSme, B2Inds, B2BoolInv, B2BI
def test_collectB2(self): from smamin_utils import col_columns_atend N = 100 n = 7 col = np.arange(0, N, n).astype(int) v = np.arange(N) v = np.append(v, 0*col) colI = np.in1d(range(len(v)), col) mat = sps.spdiags(v, [0], N, N + len(col)) MatRa = col_columns_atend(mat, col) vra = np.r_[v[~colI], v[col]] self.assertTrue(np.allclose(MatRa*vra, mat*v))
def test_rearrange_matrices(self): """check the algorithm rearranging for B2, solve the rearranged system and sort back the solution vector The rearr. is done by swapping columns in the coeff matrix, thus the resort is done by swapping the entries of the solution vector""" import dolfin import prob_defs as tts import dolfin_to_nparrays as dtn from smamin_utils import col_columns_atend, revert_sort_tob2 import smamin_thcr_mesh N = 32 mesh = smamin_thcr_mesh.getmake_mesh(N) V = dolfin.VectorFunctionSpace(mesh, "CG", 2) Q = dolfin.FunctionSpace(mesh, "CG", 1) velbcs = tts.setget_velbcs_zerosq(mesh, V) bcinds = [] for bc in velbcs: bcdict = bc.get_boundary_values() bcinds.extend(bcdict.keys()) # indices of the inner velocity nodes invinds = np.setdiff1d(range(V.dim()), bcinds) Ma, Aa, BTa, Ba, MPa = dtn.get_sysNSmats(V, Q) Mc = Ma[invinds, :][:, invinds] Bc = Ba[:, invinds] BTc = BTa[invinds, :] B2BubInds, _ = smamin_thcr_mesh.get_B2_bubbleinds(N, V, mesh) # we need the B2Bub indices in the reduced setting vc # this gives a masked array of boolean type B2BubBool = np.in1d(np.arange(V.dim())[invinds], B2BubInds) # B2BubInds = np.arange(len(B2BubIndsBool Nv = len(invinds) Np = Q.dim() dt = 1.0 / N # the complement of the bubble index in the inner nodes BubIndC = ~B2BubBool # np.setdiff1d(np.arange(Nv),B2BubBool) # the bubbles as indices B2BI = np.arange(len(B2BubBool))[B2BubBool] # Reorder the matrices for smart min ext MSme = col_columns_atend(Mc, B2BI) BSme = col_columns_atend(Bc, B2BI) B1Sme = BSme[:, :Nv - (Np - 1)] B2Sme = BSme[:, Nv - (Np - 1):] M1Sme = MSme[:, :Nv - (Np - 1)] M2Sme = MSme[:, Nv - (Np - 1):] IterA1 = sps.hstack( [sps.hstack([M1Sme, dt*M2Sme]), -dt*BTc[:, 1:]]) IterA2 = sps.hstack([sps.hstack([B1Sme[1:, :], dt*B2Sme[1:, :]]), sps.csr_matrix((Np - 1, (Np - 1)))]) # The rearranged coefficient matrix IterARa = sps.vstack([IterA1, IterA2]) IterAqq = sps.hstack([Mc, -dt*BTc[:, 1:]]) IterAp = sps.hstack([Bc[1:, :], sps.csr_matrix((Np-1, Np-1))]) # The actual coefficient matrix IterA = sps.vstack([IterAqq, IterAp]) rhs = np.random.random((Nv + Np - 1, 1)) SolActu = spsla.spsolve(IterA, rhs) SolRa = spsla.spsolve(IterARa, rhs) # Sort it back # manually SortBack = np.zeros((Nv + Np - 1, 1)) # q1 SortBack[BubIndC, 0] = SolRa[:Nv - (Np - 1)] # tq2 SortBack[B2BI, 0] = dt*SolRa[Nv - (Np - 1):Nv] SortBack[Nv:, 0] = SolRa[Nv:] SolRa = np.atleast_2d(SolRa).T # and by function SolRa[Nv - (Np - 1):Nv, 0] = dt*SolRa[Nv - (Np - 1):Nv, 0] SB2 = revert_sort_tob2(SolRa[:Nv, ], B2BI) SB2 = np.vstack([SB2, SolRa[Nv:, ]]) # SB2v = np.atleast_2d(SB2) SolActu = np.atleast_2d(SolActu) SortBack = np.atleast_2d(SortBack).T self.assertTrue(np.allclose(SolActu, SortBack, atol=1e-6)) self.assertTrue(np.allclose(SolActu, SB2.T, atol=1e-6))
def get_smamin_rearrangement(N, PrP, V=None, Q=None, invinds=None, nu=None, Pdof=None, M=None, A=None, B=None, mesh=None, addnedgeat=None, scheme='TH', fullB=None, crinicell=None): from smamin_utils import col_columns_atend from scipy.io import loadmat, savemat """ rearrange `B` and `M` for smart minimal extension and return the indices of the ext. nodes Parameters ---------- scheme : {'TH', 'CR'} toggle the scheme * 'TH' : Taylor-Hood * 'CR' : Crouzeix-Raviart crinicell : int, optional the starting cell for the 'CR' scheme, defaults to `0` addnedge : int, optional whether to add a Neumann edge in the CR scheme, defaults to `None` Returns ------- MSmeCL : (N,N) sparse matrix the rearranged mass matrix (columns and lines swapped) BSme : (K, N) sparse matrix the rearranged divergence matrix (columns swapped) B2Inds : (K, ) array indices of the nodes corresponding to the minimal extension w.r.t all nodes of the velocity space B2BoolInv : (N, ) boolean array mask of the ext. nodes w.r.t. the inner nodes in V, e.g. `v2 = v[B2BoolInv]` B2BI : (K, ) int array indices of the ext. nodes w.r.t the inner nodes in V """ Q = PrP.Q if Q is None else Q V = PrP.V if V is None else V invinds = PrP.invinds if invinds is None else invinds nu = PrP.nu if nu is None else nu mesh = PrP.mesh if mesh is None else mesh Pdof = PrP.Pdof if Pdof is None and PrP is not None else Pdof if scheme == 'TH': print 'solving index 1 -- with TH scheme' dname = 'mats/SmeMcBc_N{0}nu{1}_TH'.format(N, nu) get_b2inds_rtn = get_B2_bubbleinds args = dict(N=N, V=V, mesh=mesh) elif scheme == 'CR': print 'solving index 1 -- with CR scheme' dname = 'mats/SmeMcBc_N{0}nu{1}_CR'.format(N, nu) # pressure-DoF of B_matrix NOT removed yet! get_b2inds_rtn = get_B2_CRinds args = dict(N=N, V=V, mesh=mesh, Q=Q, inicell=crinicell, B_matrix=B, invinds=invinds) try: SmDic = loadmat(dname) pdoflist = loadmat(dname+'pdoflist') # TODO enable saving again except IOError: print 'Computing the B2 indices...' # get the indices of the B2-part B2Inds, pdoflist = get_b2inds_rtn(**args) if addnedgeat is not None: # TODO: hard coded filtering of the needed V bas func # list of columns that have a nnz at cell #addnedge potcols = fullB[addnedgeat, :].indices for col in potcols: # TODO here we need B if fullB[:, col].nnz == 1: coltoadd = col break B2Inds = np.r_[coltoadd, B2Inds] # end TODO # the B2 inds wrt to inner nodes # this gives a masked array of boolean type B2BoolInv = np.in1d(np.arange(V.dim())[invinds], B2Inds) # this as indices B2BI = np.arange(len(B2BoolInv), dtype=np.int32)[B2BoolInv] # Reorder the matrices for smart min ext... # ...the columns print 'Rearranging the matrices...' # Reorder the matrices for smart min ext... # ...the columns MSmeC = col_columns_atend(M, B2BI) BSme = col_columns_atend(B, B2BI) # ...and the lines MSmeCL = col_columns_atend(MSmeC.T, B2BI) if A is not None: ASmeC = col_columns_atend(A, B2BI) ASmeCL = (col_columns_atend(ASmeC.T, B2BI)).T print 'done' savemat(dname, {'MSmeCL': MSmeCL, 'ASmeCL': ASmeCL, 'BSme': BSme, 'B2Inds': B2Inds, 'B2BoolInv': B2BoolInv, 'B2BI': B2BI}) if scheme == 'CR': savemat(dname+'pdoflist', {'pdoflist': pdoflist}) SmDic = loadmat(dname) MSmeCL = SmDic['MSmeCL'] ASmeCL = SmDic['ASmeCL'] BSme = SmDic['BSme'] B2Inds = SmDic['B2Inds'] B2BoolInv = SmDic['B2BoolInv'] > 0 B2BoolInv = B2BoolInv.flatten() B2BI = SmDic['B2BI'] if scheme == 'CR': pdoflist = loadmat(dname+'pdoflist')['pdoflist'] else: pdoflist = None only_check_cond = False if only_check_cond: print 'Scheme is ', scheme import matplotlib.pylab as pl if Pdof is None: B2 = BSme[:, :][:, -B2Inds.size:] B2res = fullB[pdoflist.flatten(), :][:, B2Inds.flatten()] print 'condition number is ', npla.cond(B2res.todense()) # B2res = BSme[pdoflist.flatten(), :][:, -B2Inds.size:] pl.figure(2) pl.spy(B2res) # [:100, :][:, :100]) elif Pdof == 0: B2 = BSme[1:, :][:, -B2Inds.size:] print 'condition number is ', npla.cond(B2.todense()) else: raise NotImplementedError() print 'N is ', N print 'B2 shape is ', B2.shape pl.figure(1) pl.spy(B2) pl.show(block=False) import sys sys.exit('done') if fullB is not None and only_check_cond: fbsme = col_columns_atend(fullB, B2Inds.flatten()) import matplotlib.pylab as pl pl.figure(2) pl.spy(fbsme) pl.show(block=False) fbsmec = fbsme[0:, :][:, -B2Inds.size:] pl.figure(3) pl.spy(fbsmec) pl.show(block=False) if pdoflist is not None: linelist = [] for pdof in pdoflist.flatten().tolist()[1:]: linelist.append(fbsmec[pdof, :]) fbsmecr = sps.vstack(linelist) pl.figure(4) pl.spy(fbsmecr) pl.show(block=False) print 'condition number is ', npla.cond(fbsmecr.T.todense()) print 'N is ', N if A is None: return MSmeCL, BSme, B2Inds, B2BoolInv, B2BI else: return MSmeCL, ASmeCL, BSme, B2Inds, B2BoolInv, B2BI