Skip to content

dec_h1inv_intrinsic

dec_h1inv_intrinsic(l_sq, F, E_to_he=None)

Builds the inverse DEC 1-Hodge-star operator as described, for example, in Crane et al. 2013. "Digital Geometry Processing with Discrete Exterior Calculus".

The edge labeling in E_to_he follows the convention from Gpytoolbox's halfedge_edge_map.

The input mesh must be a manifold mesh.

Parameters:

Name Type Description Default
l_sq (m,3) numpy array

squared halfedge lengths as computed by halfedge_lengths_squared

required
F (m,3) numpy int array

face index list of a triangle mesh

required
E_to_he (e,2,2) numpy int array, optional (default None)

index map from e to corresponding row and col in the list of all halfedges he as computed by halfedge_edge_map for two halfedges (or -1 if only one halfedge exists) If absent, will be computed using halfedge_edge_map

None

Returns:

Name Type Description
h1inv (e,e) scipy csr_matrix

inverse of DEC operator h1

Examples:

# Mesh in V,F
l_sq = gpy.halfedge_lengths_squared(V,F)
h1inv = gpy.dec_h1inv_intrinsic(l_sq,F)
Source code in src/gpytoolbox/dec_h1inv_intrinsic.py
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
def dec_h1inv_intrinsic(l_sq,F,E_to_he=None):
    """Builds the inverse DEC 1-Hodge-star operator as described, for example,
    in Crane et al. 2013. "Digital Geometry Processing with Discrete Exterior
    Calculus".

    The edge labeling in E_to_he follows the convention from Gpytoolbox's
    `halfedge_edge_map`.

    The input mesh _must_ be a manifold mesh.

    Parameters
    ----------
    l_sq : (m,3) numpy array
        squared halfedge lengths as computed by halfedge_lengths_squared
    F : (m,3) numpy int array
        face index list of a triangle mesh
    E_to_he : (e,2,2) numpy int array, optional (default None)
        index map from e to corresponding row and col in the list of
        all halfedges `he` as computed by `halfedge_edge_map` for two
        halfedges (or -1 if only one halfedge exists)
        If absent, will be computed using `halfedge_edge_map`

    Returns
    -------
    h1inv : (e,e) scipy csr_matrix
        inverse of DEC operator h1

    Examples
    --------
    ```python
    # Mesh in V,F
    l_sq = gpy.halfedge_lengths_squared(V,F)
    h1inv = gpy.dec_h1inv_intrinsic(l_sq,F)
    ```

    """

    assert F.shape[1] == 3

    if E_to_he is None:
        _,_,_,E_to_he = halfedge_edge_map(F, assume_manifold=True)

    # A second halfedge exists for these
    se = E_to_he[:,1,0] >= 0

    C = cotangent_weights_intrinsic(l_sq,F)
    diag = C[E_to_he[:,0,0],E_to_he[:,0,1]]
    diag[se] += C[E_to_he[se,1,0],E_to_he[se,1,1]]
    h1inv = sp.sparse.diags(np.nan_to_num(1. / diag), format='csr',
        shape=(E_to_he.shape[0],E_to_he.shape[0]))

    return h1inv