Coverage for mpcforces_extractor\writer\summary_writer.py: 81%
74 statements
« prev ^ index » next coverage.py v7.6.4, created at 2024-11-06 21:34 +0100
« prev ^ index » next coverage.py v7.6.4, created at 2024-11-06 21:34 +0100
1import os
2import time
3from typing import Optional
4from mpcforces_extractor.reader.modelreaders import FemFileReader
5from mpcforces_extractor.datastructure.loads import Force, Moment
6from mpcforces_extractor.datastructure.rigids import MPC
7from mpcforces_extractor.force_extractor import MPCForceExtractor
10class SummaryWriter:
11 """
12 This class is used to write the summary of the forces extracted from the MPC forces file
13 """
15 def __init__(
16 self, instance: MPCForceExtractor, output_folder: Optional[str] = None
17 ):
18 self.instance = instance
19 if output_folder:
20 self.output_path = os.path.join(output_folder, "summary.txt")
21 else:
22 self.output_path = None
23 self.lines = []
24 self.start_time = time.time()
26 def add_header(self):
27 """
28 This method adds the header to the summary
29 """
30 timestamp = time.time()
31 local_time = time.localtime(timestamp)
32 formatted_time = time.strftime("%Y-%m-%d %H:%M:%S", local_time)
34 self.lines.append("Summary of the MPC forces extraction\n")
35 self.lines.append(f"Date: {formatted_time}\n")
36 self.lines.append(f"Input FEM file: {self.instance.fem_file_path}\n")
37 self.lines.append(f"Input MPC forces file: {self.instance.mpc_file_path}\n")
38 self.lines.append("\n")
40 def add_mpc_lines(self):
41 """
42 This method adds the lines for each MPC element to the summary
43 """
44 for mpc in self.instance.reader.rigid_elements:
45 self.add_mpc_line(mpc)
47 def add_mpc_line(self, mpc: MPC) -> None:
48 """
49 Add info for a single MPC element
50 """
51 self.lines.append(f"Rigid Element ID: {mpc.element_id}\n")
52 self.lines.append(f" MPC Config: {mpc.mpc_config.name}\n")
54 # Forces present
55 for _, load in FemFileReader.load_id2load.items():
56 load_x = round(load.compenents[0], 3)
57 load_y = round(load.compenents[1], 3)
58 load_z = round(load.compenents[2], 3)
59 # check if load is instance of force or a moment
60 load_type = "None"
61 if isinstance(load, Force):
62 load_type = "Force"
63 if isinstance(load, Moment):
64 load_type = "Moment"
66 if load.node_id in [mpc.master_node.id]:
67 self.lines.append(
68 f" {load_type} at Master ID: {load.id}; {load_x},{load_y},{load_z}\n"
69 )
70 if load.node_id in [node.id for node in mpc.nodes]:
71 self.lines.append(
72 f" {load_type} at Slave ID: {load.id}; {load_x},{load_y},{load_z}\n"
73 )
75 # 1D elements associated with the master node
76 for element1D in self.instance.reader.elements_1D:
77 if mpc.master_node in [element1D.node1, element1D.node2]:
78 self.lines.append(
79 f" 1D Element ID: {element1D.id} associated with the master Node\n"
80 )
81 master_node = mpc.master_node
83 self.lines.append(f" Master Node ID: {master_node.id}\n")
84 self.lines.append(f" Master Node Coords: {master_node.coords}\n")
85 self.lines.append(f" Slave Nodes: {len(mpc.nodes)}\n")
87 # add the force data
88 for subcase in self.instance.subcases:
89 subcase_id = subcase.subcase_id
90 subcase_time = subcase.time
91 self.lines.append(f" Subcase ID: {subcase_id}\n")
92 self.lines.append(f" Time: {subcase_time}\n")
93 for part_id, forces in mpc.get_part_id2force(subcase).items():
94 self.lines.append(f" Part ID: {part_id}\n")
95 node_ids = mpc.part_id2node_ids[part_id]
96 self.lines.append(
97 f" First 5 Slave Nodes for Location {node_ids[1:6]}\n"
98 )
99 node_ids = mpc.part_id2node_ids[part_id]
100 self.lines.append(f" Slave Nodes: {len(node_ids)}\n")
101 force_names = ["FX", "FY", "FZ", "MX", "MY", "MZ"]
102 for i, force in enumerate(forces):
103 self.lines.append(f" {force_names[i]}: {force:.3f}\n")
105 self.lines.append("\n")
107 def write_lines(self):
108 """
109 This method writes the lines to the file
110 """
111 if not self.output_path:
112 print("No output path specified - not writing summary")
113 return
115 with open(self.output_path, "w", encoding="utf-8") as file:
116 for line in self.lines:
117 file.write(line)
118 print("Summary written to", self.output_path)
119 print("..took ", round(time.time() - self.start_time, 2), "seconds")