Esempio n. 1
0
"""
from numpy import mat, zeros, sort, asarray, loadtxt, array, dot, \
     concatenate, sign, vstack, argmax, nonzero
from numpy.linalg import norm, det
from scipy.sparse import bmat
from scipy.sparse.linalg import spsolve
from matplotlib.pylab import figure, gca, triplot, show
from pydec import simplicial_complex, simplex_quivers, signed_volume

velocity = array([1.,0])
# Read the mesh
vertices = loadtxt('vertices.txt')
triangles = loadtxt('triangles.txt', dtype='int') - 1
# Make a simplicial complex from it
sc = simplicial_complex((vertices,triangles))
# Nk is number of k-simplices
N1 = sc[1].num_simplices
N2 = sc[2].num_simplices
# Permeability is k > 0 and viscosity is mu > 0
k = 1; mu = 1
# The matrix for the full linear system for Darcy in 2D, not taking into
# account the boundary conditions, is :
# [-(mu/k)star1 d1^T ]
# [    d1          Z ] 
# where Z is a zero matrix of size N2 by N2. 
# The block sizes are 
#   N1 X N1    N1 X N2
#   N2 X N1    N2 X N2

d1 = sc[1].d; star1 = sc[1].star
Esempio n. 2
0
    return A


seed(1)  # make results consistent

# Read in mesh data from file
mesh = read_mesh('mesh_example.xml')

vertices = mesh.vertices
triangles = mesh.elements

# remove some triangle from the mesh
triangles = triangles[
    list(set(range(len(triangles))) - set([30, 320, 21, 198])), :]

sc = simplicial_complex((vertices, triangles))

H = []  # harmonic forms

# decompose 4 random 1-cochains
for i in range(4):
    omega = sc.get_cochain(1)
    omega.v[:] = rand(*omega.v.shape)

    (beta, gamma, h) = hodge_decomposition(omega)

    h = h.v
    for v in H:
        h -= inner(v, h) * v
    h /= norm(h)
def plotjson(fn):
    """
    plotjson: make plots from json output of fiedler.py

    fn: the filename of the json file
    """

    fo=open(fn)
    data=json.load(fo)
    fo.close()
    if "adj" in data:
        (A,adj,Npts) = fiedler.adj_mat(data["adj"])
        #scew symetricise

        A = (A.T - A)/2

        A=A.tocoo()
        pos=A.data>0
        skew = numpy.column_stack((A.row[pos],A.col[pos],A.data[pos])).tolist()
        
        # #method from hodge decomposition driver.py
        # sc = simplicial_complex(([[el] for el in range(0,A.shape[0])],numpy.column_stack((A.row[pos],A.col[pos])).tolist()))
        # omega = sc.get_cochain(1)
        # omega.v[:] = A.data[pos]
        # p = omega.k
        # alpha = sc.get_cochain(p - 1)
        # #beta  = sc.get_cochain(p + 1)    

        # # Solve for alpha
        # A2 = delta(d(sc.get_cochain_basis(p - 1))).v
        # b = delta(omega).v
        # rank=cg( A2, b, tol=1e-8 )[0]

        # method from ranking driver.py

        asc = abstract_simplicial_complex([numpy.column_stack((A.row[pos],A.col[pos])).tolist()])
        B1 = asc.chain_complex()[1] # boundary matrix
        rank = lsqr(B1.T, A.data[pos])[0] # solve least squares problem
        
        sc = simplicial_complex(([[el] for el in range(0,A.shape[0])],numpy.column_stack((A.row[pos],A.col[pos])).tolist()))
        omega = sc.get_cochain(1)
        omega.v[:] = A.data[pos]
        p = omega.k
        alpha = sc.get_cochain(p - 1)
        
        alpha.v = rank
        v = A.data[pos]-d(alpha).v
        
        cyclic_adj_list=numpy.column_stack((A.row[pos],A.col[pos],v)).tolist()
        div_adj_list=numpy.column_stack((A.row[pos],A.col[pos],d(alpha).v)).tolist()

        data["hodge"]=list(rank)
        data["hodgerank"]=list(numpy.argsort(numpy.argsort(rank)))
        fo = open(fn,"w")
        json.dump(data,fo, indent=2)
        fo.close()

        fn=fn+".abstract"
        #fiedler.doPlots(numpy.array(data["f1"]),numpy.array(data["f2"]),numpy.array(data["d"]),cyclic_adj_list,fn+".decomp.cyclic.",widths=[6],vsdeg=False,nByi=data["nByi"],directed=True)
        #fiedler.doPlots(numpy.array(data["f1"]),numpy.array(data["f2"]),numpy.array(data["d"]),div_adj_list,fn+".decomp.acyclic.",widths=[6],vsdeg=False,nByi=data["nByi"],directed=True)
        #fiedler.doPlots(numpy.array(data["f1"]),numpy.array(data["f2"]),numpy.array(data["d"]),data["adj"],fn+".decomp.acyclic.over.all.",widths=[6],vsdeg=False,nByi=data["nByi"],adj_list2=div_adj_list,directed=True)
        #fiedler.doPlots(numpy.array(data["f1"]),-1*numpy.array(rank),numpy.array(data["d"]),cyclic_adj_list,fn+".decomp.harmonic.v.grad.",widths=[6],heights=[2],vsdeg=False,nByi=data["nByi"],directed=True)
        #fiedler.doPlots(numpy.array(data["f1"]),-1*numpy.array(rank),numpy.array(data["d"]),skew,fn+".decomp.skew.v.grad.",widths=[6],heights=[2],vsdeg=False,nByi=data["nByi"],directed=True)
        #fiedler.doPlots(numpy.array(data["f1"]),-1*numpy.array(rank),numpy.array(data["d"]),data["adj"],fn+".decomp.acyclic.over.all.v.grad.",widths=[6],heights=[2],vsdeg=False,nByi=data["nByi"],adj_list2=div_adj_list,directed=True)
        fiedler.doPlots(numpy.array(data["f1"]),-1*numpy.array(rank),numpy.array(data["d"]),data["adj"],fn+".all.v.grad.",widths=[24],heights=[6],vsdeg=False,nByi=data["nByi"],directed=False)
def get_eigs_PyDEC(meshname, use_FEM, quiet=False, draw=False, load=False):
    # Loading the mesh and constructing the simplicial complex
    if not quiet:
        print("")
        print("Loading '%s'..." % meshname)

    vers, tris = load_mesh(meshname)
    triangulation = tri.Triangulation(vers[:, 0], vers[:, 1], triangles=tris)
    sc = simplicial_complex((vers, tris))
    N0 = sc[0].num_simplices

    if use_FEM:
        meshname += "_FEM"

    interpolate = True
    if draw:  # Draw the mesh
        figure()
        gca().triplot(vers[:, 0], vers[:, 1], tris)
        show()

    if load:
        if not quiet:
            print("Loading matrix...")
        A = scipy.sparse.load_npz('eigen/%s/A.npz' % meshname)
    else:
        mkdirs(meshname)

        # Constructing the matrix equation Ax = b
        # A is of the form
        # [ 0  L ] N0
        # [ L  0 ] N0
        #  N0 N0
        #
        # The Laplacian L is dependent on whether we are
        #   using finite elements (Whitney 1-forms)

        if not quiet:
            print("Constructing matrix...")
        if use_FEM:
            L = sc[0].d.T * whitney_innerproduct(sc, 1) * sc[0].d
        else:
            L = sc[0].d.T * sc[1].star * sc[0].d

        # This matrix takes a long time to construct for large meshes
        A = scipy.sparse.bmat([[None, L], [L, None]], format='csr')
        scipy.sparse.save_npz('eigen/%s/A.npz' % meshname, A)

    b = np.zeros(N0 + N0)
    all_Us = np.zeros(N0)
    all_Vs = np.zeros(N0)

    # Finding points and indices for the boundary and interior
    # We don't have to convert the simplices to indices with
    # sc[0].simplex_to_index[...], because the nth 0-simplex is named n.
    b_is = np.unique(sc.boundary())
    i_is = np.delete(np.arange(N0), b_is, 0)

    # Number of internal and external points
    N0b = len(b_is)
    N0i = N0 - N0b

    # Making sure that all the indices are accounted for
    assert (N0i == len(i_is))

    if N0i == 0:
        if not quiet:
            print("No internal points in mesh! Finishing...")

        np.savetxt("eigen/" + meshname + "/l_final.txt", np.array([]))
        np.savetxt("eigen/" + meshname + "/l_final.txt", np.array([]))

        if not quiet:
            print("Done.")

        return np.array([]), np.array([])

    # Adjusting the system with U and V equal to 0 on the boundary
    # Same as the method used by Hirani in the Darcy flow example from
    # 'PyDEC: Software and Algorithms for Discretization of Exterior Calculus'
    b = b - A * np.concatenate((all_Us, all_Vs))
    keep = np.concatenate((i_is, i_is + N0))
    b = b[keep]
    A = A[keep][:, keep]

    if not quiet:
        print("Converting to PETSc...")

    A_petsc = CSR_to_PETSc(A, quiet)

    if not quiet:
        print("Preparing eigensolver...")

    # Create eigensolver
    # If the eigenvectors are taking too long to converge, either
    # increase the tolerance or decrease the max iterations
    eigensolver = SLEPcEigenSolver(A_petsc)
    eigensolver.parameters['spectrum'] = 'target magnitude'
    eigensolver.parameters[
        'spectral_transform'] = 'shift-and-invert'  # find the smallest eigenvalues first
    eigensolver.parameters['spectral_shift'] = 1e-6
    eigensolver.parameters['tolerance'] = 1e-15
    eigensolver.parameters['maximum_iterations'] = int(1e4)
    #    eigensolver.parameters["problem_type"] = "hermitian"

    # Compute all eigenvalues of A x = \lambda x
    if not quiet:
        print("Computing eigenvalues...", end=' ')
    eigensolver.solve(1000)  # number of eigenvectors to compute
    num_eigs = eigensolver.get_number_converged()

    if not quiet:
        print("(Found %d)" % num_eigs)

    lambdas = np.zeros(num_eigs)
    vs = np.zeros((num_eigs, N0i * 2))

    if not quiet:
        print("Computing eigenvectors...")

    next_update_time = time.time() + time_step
    for i in range(num_eigs):
        r, c, rx, cx = eigensolver.get_eigenpair(i)
        lambdas[i] = r
        vs[i] = rx.vec().getArray()

        np.savetxt("eigen/" + meshname + "/vectors/l%04d.txt" % i,
                   np.array([lambdas[i]]))
        np.savetxt("eigen/" + meshname + "/vectors/v%04d.txt" % i, vs[i])

        if not quiet and time.time() > next_update_time:
            if draw:
                full_eigenvector = np.zeros(N0)
                full_eigenvector[i_is] = vs[i][:N0i]
                figure()
                if interpolate:
                    gca().tricontourf(triangulation,
                                      full_eigenvector,
                                      cmap='seismic')
                else:
                    gca().scatter(vers[:, 0],
                                  vers[:, 1],
                                  c=full_eigenvector,
                                  cmap='seismic',
                                  linewidth=0.5)
                show()
            next_update_time = time.time() + time_step
            print("%4d / %4d (%3d%% )" % (i + 1, num_eigs,
                                          ((i + 1) * 100) // num_eigs))

    if not quiet:
        print("Done.")

    # We only want the real part
    lambdas = np.array(lambdas)
    vs = np.array(vs)

    # Retain only the positive eigenvalues, sorted in ascending order
    keep = lambdas > 0
    vs = vs[keep]
    lambdas = lambdas[keep]

    order = lambdas.argsort()
    lambdas = lambdas[order]
    vs = vs[order]

    # Reinserting the initial conditions and changing the ordering of axes.
    # Now final_vs[i, :] gives the ith eigenvector, instead of vs[:N0i,i] giving
    # the ith eigenvalue on the internal mesh points.
    final_vs = np.zeros((vs.shape[0], N0))
    final_vs[:, i_is] = vs[:, :N0i]

    np.savetxt("eigen/" + meshname + "/l_final.txt", lambdas)
    np.savetxt("eigen/" + meshname + "/v_final.txt", final_vs)

    if draw and not quiet:  # Draw some eigenstates
        for i in range(min(5, len(final_vs))):
            figure()
            gca().set_title("Eigenvector for lambda[%d] = %f" %
                            (i, lambdas[i]))
            if interpolate:
                gca().tricontourf(triangulation, final_vs[i], cmap='seismic')
            else:
                gca().scatter(vers[:, 0],
                              vers[:, 1],
                              c=final_vs[i],
                              cmap='seismic',
                              linewidth=0.5)
            show()

    return lambdas, final_vs
Esempio n. 5
0
import numpy as np
from scipy.io import loadmat, savemat
from pydec import simplicial_complex, whitney_innerproduct

X = loadmat('pyamg.mat')
del X['__version__']
del X['__header__']
del X['__globals__']

sc = simplicial_complex(X['vertices'], X['elements'].astype('intc'))

d = sc[0].d
M = whitney_innerproduct(sc, 1)
A = d.T.tocsr() * M * d

X['A'] = A
X['B'] = np.ones((A.shape[0], 1))

savemat('pyamg.mat', X)