Skip to content

Commit

Permalink
Merge pull request #217 from ritchie46/removeElementOrphanedNodes
Browse files Browse the repository at this point in the history
Remove orphaned nodes in remove_element()
  • Loading branch information
smith120bh authored Oct 30, 2023
2 parents b565110 + 276c01a commit 3ffa884
Show file tree
Hide file tree
Showing 3 changed files with 87 additions and 1 deletion.
10 changes: 9 additions & 1 deletion anastruct/fem/system.py
Original file line number Diff line number Diff line change
Expand Up @@ -477,12 +477,20 @@ def remove_element(self, element_id: int) -> None:
element_id (int): ID of the element to remove
"""
element = self.element_map[element_id]
for node_id in (element.node_id1, element.node_id2):
node_id1 = element.node_id1
node_id2 = element.node_id2

# Remove element object itself from node maps
for node_id in (node_id1, node_id2):
self.node_element_map[node_id].remove(element)
if len(self.node_element_map[node_id]) == 0:
self.node_element_map.pop(node_id)
self.node_map[node_id].elements.pop(element_id)
# Check if node is now orphaned, and remove it and its loads if so
if len(self.node_map[node_id].elements) == 0:
system_components.util.remove_node_id(self, node_id)

# Remove element_id
self.element_map.pop(element_id)
if element_id in self.loads_q:
self.loads_q.pop(element_id)
Expand Down
50 changes: 50 additions & 0 deletions anastruct/fem/system_components/util.py
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,56 @@ def append_node_id(
system.node_map[node_id2] = Node(node_id2, vertex=point_2)


def remove_node_id(
system: "SystemElements",
node_id: int,
) -> None:
"""Remove the node id from the system
Note that this function does NOT check if the node is still used in the system. It is
intended to be used as a helper function to `remove_element()` and others, not to be
used directly by users.
Args:
system (SystemElements): System in which the node is located
node_id (int): Node id of the node
"""
node = system.node_map[node_id]
system._vertices.pop(system.node_map[node_id].vertex)
system.node_map.pop(node_id)
if node_id in system.loads_point:
system.loads_point.pop(node_id)
if node_id in system.loads_moment:
system.loads_moment.pop(node_id)
if node in system.supports_fixed:
system.supports_fixed.remove(node)
if node in system.supports_hinged:
system.supports_hinged.remove(node)
if node in system.supports_rotational:
system.supports_rotational.remove(node)
if node in system.internal_hinges:
system.internal_hinges.remove(node)
if node in system.supports_roll:
ind = system.supports_roll.index(node)
system.supports_roll.remove(node)
system.supports_roll_direction.pop(ind)
system.supports_roll_rotate.pop(ind)
if node_id in system.inclined_roll:
system.inclined_roll.pop(node_id)
if node in [item[0] for item in system.supports_spring_x]:
ind = [item[0] for item in system.supports_spring_x].index(node)
system.supports_spring_x.pop(ind)
if node in [item[0] for item in system.supports_spring_y]:
ind = [item[0] for item in system.supports_spring_y].index(node)
system.supports_spring_y.pop(ind)
if node in [item[0] for item in system.supports_spring_z]:
ind = [item[0] for item in system.supports_spring_z].index(node)
system.supports_spring_z.pop(ind)
if node_id in [item[0] for item in system.supports_spring_args]:
ind = [item[0] for item in system.supports_spring_args].index(node_id)
system.supports_spring_args.pop(ind)


def det_vertices(
system: "SystemElements",
location_list: Union[
Expand Down
28 changes: 28 additions & 0 deletions tests/test_e2e.py
Original file line number Diff line number Diff line change
Expand Up @@ -1016,3 +1016,31 @@ def it_results_in_correct_deflections():
assert system.get_node_results_system(1)["uy"] == approx(
-w * l**4 / (8 * EI)
)

def context_remove_element():
@pspec_context("Removing an element from a propped beam")
def describe():
pass

system = SystemElements()
system.add_element([[0, 0], [10, 0]])
system.add_element([[10, 0], [15, 0]])
system.add_support_hinged(1)
system.add_support_hinged(2)
system.q_load(q=-1, element_id=1)
system.q_load(q=-1, element_id=2)
system.point_load(node_id=3, Fy=-10)
system.remove_element(2)
system.solve()

def it_removes_element():
assert len(system.element_map) == 1
assert not (2 in system.loads_q)

def it_removes_orphaned_node():
assert len(system.node_map) == 2
assert not (3 in system.loads_point)

def it_results_in_correct_reactions():
assert system.get_node_results_system(1)["Fy"] == approx(-5)
assert system.get_node_results_system(2)["Fy"] == approx(-5)

0 comments on commit 3ffa884

Please sign in to comment.