Skip to content

tna

least_squares_tna(coords, is_support, edge_index, q_target, verbose=False)

Finds the least squares force densities with respect to target force densities that preserve x and y coordinates consistent with Thrust Network Analysis (TNA).

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
q_target Tensor

A tensore of shape (num_edges) containing the target force density for each edge.

required
Source code in src/torch_structure/formfinding/tna.py
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
def least_squares_tna(coords, is_support, edge_index, q_target, verbose=False):
    """
    Finds the least squares force densities with respect to target force densities that preserve x and y coordinates
    consistent with Thrust Network Analysis (TNA).

    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.
        q_target (torch.Tensor): A tensore of shape (num_edges) containing the target force density for each edge.
    """
    q_target = q_target.view(-1)

    basis_vectors = create_xy_equilibrium_space(coords, is_support, edge_index)
    vector_coefficients = torch.linalg.lstsq(basis_vectors, q_target).solution
    q = torch.mv(basis_vectors, vector_coefficients)

    if verbose:
        print(
            f"Least Squares TNA number of degrees of freedom: {basis_vectors.shape[1]}"
        )

    return q.unsqueeze(1)

tna(coords, is_support, load, edge_index, q_target, verbose=False)

Performs the Thrust Network Analysis (TNA) formfinding algorithm by finding the least squares force densities with respect to target force densities that preserve x and y coordinates.

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
load Tensor

A tensor of shape (num_nodes, 3) containing the load vector applied at each node.

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
q_target Tensor

A tensore of shape (num_edges) containing the target force density for each edge.

required
verbose bool

If True, prints the number of degrees of freedom in the least squares TNA solution.

False
Source code in src/torch_structure/formfinding/tna.py
 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
def tna(
    coords, is_support, load, edge_index, q_target, verbose=False
):  # only works for directed graphs
    """
    Performs the Thrust Network Analysis (TNA) formfinding algorithm by finding the
    least squares force densities with respect to target force densities that preserve
    x and y coordinates.

    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.
        load (torch.Tensor): A tensor of shape (num_nodes, 3) containing the load vector
            applied at each node.
        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.
        q_target (torch.Tensor): A tensore of shape (num_edges) containing the target
            force density for each edge.
        verbose (bool): If True, prints the number of degrees of freedom in the least
            squares TNA solution.

    """
    force_density = least_squares_tna(coords, is_support, edge_index, q_target, verbose)
    coords, force = fdm(
        coords,
        load,
        is_support,
        edge_index,
        force_density,
        directed=True,
        use_batching=False,
        solve_only_z=True,
    )
    return coords, force, force_density