Coverage for mpcforces_extractor\datastructure\rigids.py: 98%
48 statements
« prev ^ index » next coverage.py v7.6.4, created at 2024-11-13 12:05 +0100
« prev ^ index » next coverage.py v7.6.4, created at 2024-11-13 12:05 +0100
1from typing import Dict, List
2from enum import Enum
3from mpcforces_extractor.datastructure.entities import Node, Element
4from mpcforces_extractor.datastructure.subcases import Subcase
7class MPC_CONFIG(Enum):
8 """
9 Enum to represent the MPC configuration
10 """
12 RBE2 = 1
13 RBE3 = 2
16class MPC:
17 """
18 This class is a Multiple Point Constraint (MPC) class that is used to store the nodes and the dofs
19 """
21 config_2_id_2_instance: Dict[int, "MPC"] = {}
23 def __init__(
24 self,
25 *, # fixes the too many positional arguments error from the linter by forcing the use of keyword arguments
26 element_id: int,
27 mpc_config: MPC_CONFIG,
28 master_node: Node,
29 nodes: List,
30 dofs: str,
31 ):
32 self.element_id: int = element_id
33 self.mpc_config: MPC_CONFIG = mpc_config
34 if master_node is None:
35 print("Master_node2coords is None for element_id", element_id)
36 self.master_node = master_node
37 self.nodes: List = nodes
38 self.dofs: int = dofs
39 self.part_id2node_ids = {}
41 # config_2_id_2_instance
42 if mpc_config.value not in MPC.config_2_id_2_instance:
43 MPC.config_2_id_2_instance[mpc_config.value] = {}
45 if element_id in MPC.config_2_id_2_instance[mpc_config.value]:
46 print("MPC element_id already exists", element_id)
47 MPC.config_2_id_2_instance[mpc_config.value][element_id] = self
49 @staticmethod
50 def reset():
51 """
52 This method is used to reset the instances
53 """
54 MPC.config_2_id_2_instance = {}
56 def get_part_id2force(self, subcase: Subcase) -> Dict:
57 """
58 This method is used to get the forces for each part of the MPC (connected slave nodes)
59 """
61 if not self.part_id2node_ids:
62 # Connected groups of nodes - get then the intersection with the slave nodes
63 part_id2connected_node_ids = Element.get_part_id2node_ids_graph()
64 part_id2node_ids = {}
65 mpc_node_ids = [node.id for node in self.nodes]
66 mpc_node_ids.append(self.master_node.id)
67 for part_id, node_ids in part_id2connected_node_ids.items():
68 part_id2node_ids[part_id] = list(
69 set(node_ids).intersection(mpc_node_ids)
70 )
72 self.part_id2node_ids = part_id2node_ids
74 # Calculate the summed forces for each part
75 part_id2forces = {}
76 for part_id, node_ids in self.part_id2node_ids.items():
77 sum_forces = [0, 0, 0]
78 if subcase is not None:
79 sum_forces = subcase.get_sum_forces(node_ids)
80 part_id2forces[part_id] = sum_forces
81 return part_id2forces
83 def get_subcase_id2part_id2force(self) -> Dict:
84 """
85 This method is used to get the forces for each part of the MPC (connected slave nodes)
86 """
88 subcase_id2part_id2forces = {}
89 for subcase in Subcase.subcases:
90 part_id2forces = self.get_part_id2force(subcase)
91 subcase_id2part_id2forces[subcase.subcase_id] = part_id2forces
92 return subcase_id2part_id2forces