Skip to content

utils

create_branch_node_matrix(edge_index)

Creates the branch-node matrix for a given set of edges.

Parameters:

Name Type Description Default
edge_index Tensor

A tensor of shape (2, num_edges) containing the indices of the nodes that form each edge.

required

Returns:

Type Description

torch.Tensor: A dense tensor of shape (num_edges, num_nodes) representing the branch-node incidence matrix. The matrix has an entry of +1 and -1 for each row indicating the start and end nodes of each edge, respectively.

Source code in src/torch_structure/formfinding/utils.py
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
def create_branch_node_matrix(edge_index):
    """
    Creates the branch-node matrix for a given set of edges.

    Args:
        edge_index (torch.Tensor): A tensor of shape (2, num_edges) containing the indices of the nodes that form each edge.

    Returns:
        torch.Tensor: A dense tensor of shape (num_edges, num_nodes) representing the branch-node incidence matrix.
            The matrix has an entry of +1 and -1 for each row indicating the start and end nodes of each edge, respectively.
    """
    device = edge_index.device
    num_edges = edge_index.size(1)
    num_nodes = torch.max(edge_index) + 1
    row_indices = torch.arange(num_edges, device=device).repeat(2)
    col_indices = edge_index.view(-1)
    indices = torch.stack([row_indices, col_indices])
    values = torch.cat(
        [torch.ones(num_edges, device=device), -torch.ones(num_edges, device=device)]
    )
    branch_node_matrix = torch.sparse_coo_tensor(
        indices, values, size=(num_edges, num_nodes)
    ).to_dense()
    return branch_node_matrix

create_xy_equilibrium_matrix(coords, is_support, edge_index)

Creates the equilibrium matrix for the x and y components of the equilibrium equations.

Parameters:

Name Type Description Default
coords Tensor

A tensor of shape (num_nodes, 3) containing the 3D coordinates of each node. Only the x and y coordinates have an effect on the output.

required
is_support Tensor

A boolean tensor of shape (num_nodes, 1) indicating which nodes are fixed (True) or free (False).

required
edge_index Tensor

A tensor of shape (2, num_edges) containing the indices of the nodes that form each edge. Needs to be directed.

required
Source code in src/torch_structure/formfinding/utils.py
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
def create_xy_equilibrium_matrix(coords, is_support, edge_index):
    """
    Creates the equilibrium matrix for the x and y components of the equilibrium equations.

    Args:
        coords (torch.Tensor): A tensor of shape (num_nodes, 3) containing the 3D coordinates of each node. Only
            the x and y coordinates have an effect on the output.
        is_support (torch.Tensor): A boolean tensor of shape (num_nodes, 1) indicating which nodes are fixed (True) or free (False).
        edge_index (torch.Tensor): A tensor of shape (2, num_edges) containing the indices of the nodes that form each edge. Needs to be directed.
    """
    is_support = is_support.view(-1)

    coords = torch.clone(coords)  # check if this is necessary

    C = create_branch_node_matrix(edge_index)
    C_free = C[:, ~is_support]
    C_free_transposed = torch.transpose(C_free, 0, 1)

    u = torch.mv(C, coords[:, 0])
    v = torch.mv(C, coords[:, 1])
    U = torch.diag(u)
    V = torch.diag(v)
    A = torch.vstack((torch.mm(C_free_transposed, U), torch.mm(C_free_transposed, V)))

    return A

create_xy_equilibrium_space(coords, is_support, edge_index)

Compute a basis for the space of xy-equilibrium-preserving coordinate perturbations.

Builds the xy equilibrium matrix and returns a basis of its null space, i.e. the directions in which free-node xy-coordinates can move while keeping the horizontal equilibrium equations satisfied.

Parameters:

Name Type Description Default
coords Tensor[N, 3]

node coordinates; only x and y affect the result.

required
is_support (Tensor[N, 1], bool)

mask of fixed (supported) nodes.

required
edge_index Tensor[2, E]

directed edge connectivity.

required

Returns:

Type Description

torch.Tensor [D, K]: basis vectors (columns) spanning the null space

of the xy equilibrium matrix, where D is twice the number of

free nodes.

Source code in src/torch_structure/formfinding/utils.py
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 create_xy_equilibrium_space(coords, is_support, edge_index):
    """Compute a basis for the space of xy-equilibrium-preserving coordinate perturbations.

    Builds the xy equilibrium matrix and returns a basis of its null space,
    i.e. the directions in which free-node xy-coordinates can move while
    keeping the horizontal equilibrium equations satisfied.

    Args:
        coords (torch.Tensor [N, 3]): node coordinates; only x and y affect
            the result.
        is_support (torch.Tensor [N, 1], bool): mask of fixed (supported)
            nodes.
        edge_index (torch.Tensor [2, E]): directed edge connectivity.

    Returns:
        torch.Tensor [D, K]: basis vectors (columns) spanning the null space
        of the xy equilibrium matrix, where ``D`` is twice the number of
        free nodes.
    """
    coords = torch.clone(coords)  # check if this is necessary

    A = create_xy_equilibrium_matrix(coords, is_support, edge_index)

    basis_vectors = scipy.linalg.null_space(A.cpu().numpy())  # consider using torch
    basis_vectors = torch.tensor(basis_vectors, dtype=torch.float32)

    return basis_vectors