(V, E, return_edges=False)
return V, E
Generate a quadratic element list by adding midpoints to each edge.

    Parameters
    ----------
    V : ndarray
        nv x 2 list of coordinates

    E : ndarray
        ne x 3 list of vertices

    return_edges : bool
        indicate whether list of the refined edges is returned

    Returns
    -------
    V2 : ndarray
        nv2 x 2 list of coordinates

    E2 : ndarray
        ne2 x 6 list of vertices

    Edges : ndarray
        ned x 2 list of edges where the midpoint is generated

    Notes
    -----
        - midpoints are introduced and globally numbered at the end of the vertex list
        - the element list includes the new list beteen v0-v1, v1-v2, and v2-v0

    Examples
    --------
    >>> import numpy as np
    >>> from pyamg.gallery import fem
    >>> V = np.array([[0.,0.], [1.,0.], [0.,1.], [1.,1.]])
    >>> E = np.array([[0,1,2], [2,3,1]])
    >>> V2, E2 = fem.generate_quadratic(V, E)
    >>> print(V2)
    [[0.  0. ]
     [1.  0. ]
     [0.  1. ]
     [1.  1. ]
     [0.5 0. ]
     [0.5 0.5]
     [0.  0.5]
     [0.5 1. ]
     [1.  0.5]]
    >>> print(E2)
    [[0 1 2 4 5 6]
     [2 3 1 7 8 5]]
Generate a quadratic element list by adding midpoints to each edge.
Generate a quadratic element list by adding midpoints to each edge .
def generate_quadratic(V, E, return_edges=False):
    """Generate a quadratic element list by adding midpoints to each edge.

    Parameters
    ----------
    V : ndarray
        nv x 2 list of coordinates

    E : ndarray
        ne x 3 list of vertices

    return_edges : bool
        indicate whether list of the refined edges is returned

    Returns
    -------
    V2 : ndarray
        nv2 x 2 list of coordinates

    E2 : ndarray
        ne2 x 6 list of vertices

    Edges : ndarray
        ned x 2 list of edges where the midpoint is generated

    Notes
    -----
        - midpoints are introduced and globally numbered at the end of the vertex list
        - the element list includes the new list beteen v0-v1, v1-v2, and v2-v0

    Examples
    --------
    >>> import numpy as np
    >>> from pyamg.gallery import fem
    >>> V = np.array([[0.,0.], [1.,0.], [0.,1.], [1.,1.]])
    >>> E = np.array([[0,1,2], [2,3,1]])
    >>> V2, E2 = fem.generate_quadratic(V, E)
    >>> print(V2)
    [[0.  0. ]
     [1.  0. ]
     [0.  1. ]
     [1.  1. ]
     [0.5 0. ]
     [0.5 0.5]
     [0.  0.5]
     [0.5 1. ]
     [1.  0.5]]
    >>> print(E2)
    [[0 1 2 4 5 6]
     [2 3 1 7 8 5]]
    """
    if not isinstance(V, np.ndarray) or not isinstance(E, np.ndarray):
        raise ValueError('V and E must be ndarray')

    if V.shape[1] != 2 or E.shape[1] != 3:
        raise ValueError('V should be nv x 2 and E should be ne x 3')

    ne = E.shape[0]

    # make a vertext-to-vertex graph
    ID = np.kron(np.arange(0, ne), np.ones((3,), dtype=int))
    G = sparse.coo_matrix((np.ones((ne*3,), dtype=int), (E.ravel(), ID,)))
    V2V = G * G.T

    # from the vertex graph, get the edges and create new midpoints
    V2Vmid = sparse.tril(V2V, -1)
    Edges = np.vstack((V2Vmid.row, V2Vmid.col)).T
    Vmid = (V[Edges[:, 0], :] + V[Edges[:, 1], :]) / 2.0
    V = np.vstack((V, Vmid))

    # enumerate the new midpoints for the edges
    # V2Vmid[i,j] will have the new number of the midpoint between i and j
    maxindex = E.max() + 1
    newID = maxindex + np.arange(Edges.shape[0])
    V2Vmid.data = newID
    V2Vmid = V2Vmid + V2Vmid.T

    # from the midpoints, extend E
    E = np.hstack((E, np.zeros((E.shape[0], 3), dtype=int)))
    E[:, 3] = V2Vmid[E[:, 0], E[:, 1]]
    E[:, 4] = V2Vmid[E[:, 1], E[:, 2]]
    E[:, 5] = V2Vmid[E[:, 2], E[:, 0]]

    if return_edges:
        return V, E, Edges

    return V, E
def generate_quadratic ( V , E , return_edges = False ) : if not isinstance ( V , np . ndarray ) or not isinstance ( E , np . ndarray ) : raise ValueError ( 'V and E must be ndarray' ) if V . shape [ 1 ] != 2 or E . shape [ 1 ] != 3 : raise ValueError ( 'V should be nv x 2 and E should be ne x 3' ) ne = E . shape [ 0 ] # make a vertext-to-vertex graph ID = np . kron ( np . arange ( 0 , ne ) , np . ones ( ( 3 , ) , dtype = int ) ) G = sparse . coo_matrix ( ( np . ones ( ( ne * 3 , ) , dtype = int ) , ( E . ravel ( ) , ID , ) ) ) V2V = G * G . T # from the vertex graph, get the edges and create new midpoints V2Vmid = sparse . tril ( V2V , - 1 ) Edges = np . vstack ( ( V2Vmid . row , V2Vmid . col ) ) . T Vmid = ( V [ Edges [ : , 0 ] , : ] + V [ Edges [ : , 1 ] , : ] ) / 2.0 V = np . vstack ( ( V , Vmid ) ) # enumerate the new midpoints for the edges # V2Vmid[i,j] will have the new number of the midpoint between i and j maxindex = E . max ( ) + 1 newID = maxindex + np . arange ( Edges . shape [ 0 ] ) V2Vmid . data = newID V2Vmid = V2Vmid + V2Vmid . T # from the midpoints, extend E E = np . hstack ( ( E , np . zeros ( ( E . shape [ 0 ] , 3 ) , dtype = int ) ) ) E [ : , 3 ] = V2Vmid [ E [ : , 0 ] , E [ : , 1 ] ] E [ : , 4 ] = V2Vmid [ E [ : , 1 ] , E [ : , 2 ] ] E [ : , 5 ] = V2Vmid [ E [ : , 2 ] , E [ : , 0 ] ] if return_edges : return V , E , Edges return V , E