From 6fac599ea00e6354c1d5bbf73ae849bfe0ab6b8b Mon Sep 17 00:00:00 2001 From: Simon Steuer Date: Tue, 4 Oct 2022 13:50:03 +0200 Subject: [PATCH] ersten STand des Werkzeugs dazu eingepflegt --- rectengular_cs.py | 147 ++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 147 insertions(+) create mode 100644 rectengular_cs.py diff --git a/rectengular_cs.py b/rectengular_cs.py new file mode 100644 index 0000000..89f6ccd --- /dev/null +++ b/rectengular_cs.py @@ -0,0 +1,147 @@ +import argparse +from matplotlib import pyplot as plt +from math import floor + + +class ProfileHeights: + + bobbin_train_segment_types = {165: 0.38, 210: 0.248, 225: 0.354648} # Key = Spulenzug-Typ - Value = Gewicht + + def __init__(self, + cross_section_type, + datum, + width, + thickness, + ap_positions=None, + beam_length=2000, + min_ap_distance=200, + yield_strength=235, + segment_type=165, + bobbin_mass=4, + column_distance=3.6, + ): + + self.cross_section_type = cross_section_type + self.datum = datum + self.width = width + self.thickness = thickness + self.ap_positions = ap_positions + self.beam_length = beam_length + self.min_ap_distance = min_ap_distance + self.yield_strength = yield_strength + self.segment_type = segment_type + self.bobbin_mass = bobbin_mass + self.column_distance = column_distance + + def ap_position_check(self): + # Überprüft, ob alle AP's den zulässigen Mindestabstand zueinander einhalten + + if not [abs(new_pos - old_pos) < self.min_ap_distance for old_pos, new_pos in zip(self.ap_positions, self.ap_positions[1:])]: + raise ValueError(f"Abstände zwischen ") + else: + return True + + def ap_amount(self): + return floor(self.beam_length / self.min_ap_distance) + + def individual_ap_positions(self): + # Funktion gibt Einzelabstände der AP-Profile zur Säule zurück + + # Fall 1: Es wurden keine Einzelabstände zur Säule definiert. Abstand zwischen AP's = zulässiger Mindestabstand + # Fall 2: Es wurden individuelle AP-Abstände definiert. + + if self.ap_positions is None: + return [ap_count * self.min_ap_distance for ap_count in range(1, self.ap_amount() + 1)] + elif self.ap_position_check(): + return self.ap_positions + + def force_per_ap_meter(self): + if self.bobbin_mass > 4: + raise ValueError(f"Gewicht der Spulen darf max. 4 kg betragen!") + else: + column_rows = 2 + location_factor = 9.81 # m/s^2 + ap_weight_per_meter = 1.88 + + total_bobbin_mass = self.bobbin_mass * (1000 / self.segment_type) + mass = total_bobbin_mass + 2 * self.bobbin_train_segment_types[self.segment_type] + ap_weight_per_meter + + return mass * location_factor * self.column_distance / column_rows + + def ref_moment_of_resistance(self, current_beam_length, ap_column_distances, force_per_rail): + # Funktion berechnet Widerstandsmoment für die aktuelle Trägerlänge + + total_column_distance = 0 + for ap_column_distance in ap_column_distances: + if current_beam_length >= ap_column_distance: + total_column_distance += ap_column_distance + else: + break + + safety_factor = 1.7 + bend_moment = force_per_rail * total_column_distance + allowed_bend_stress = (self.yield_strength * 1.2) / safety_factor + + return bend_moment / allowed_bend_stress + + def recalculated_moment_of_resistance(self, height): + # Berechnet das Widerstandsmoment mit der derzeitigen Profilhöhe für verschiedene Querschnitts-Arten + + inner_width = self.width - 2 * self.thickness + inner_height = height - 2 * self.thickness + bar_width = self.width - self.thickness + + # 1. Widerstandsmoment-Berechnung für idealisiertes rechteckiges Hohlprofil: + if self.cross_section_type == "hohlprofil": + return (self.width * height ** 3 - inner_width * inner_height ** 3) / (6 * height) + + # 2. Widerstandsmoment-Berechnung für idealisiertes IPE-Profil / C-Profil: + elif self.cross_section_type in ["c", "ipe"]: + return (self.width * height ** 3 - bar_width * inner_height ** 3) / (6 * height) + + def datum_reference(self): + # Legt fest, ob die notwendige Profilhöhe im Plot in Abhängigkeit von jedem Millimeter der Gesamtlänge [l] + # des Trägers oder der Trägerlänge an der Stelle jedes AP-Profils [n] dargestellt werden soll. + + if self.datum == "l": + return list(range(self.min_ap_distance, self.beam_length + 1)) + + elif self.datum == "n": + return self.individual_ap_positions() + + def height_calculation(self): + + start_height = 2 * self.thickness + + beam_lengths = self.datum_reference() + ap_column_distance = self.individual_ap_positions() + force_per_ap_meter = self.force_per_ap_meter() + + heights = [] + lengths = [] + moment_of_resistances = [] + recalculated_moment_of_resistance = 0 + + for count, beam_length in enumerate(beam_lengths): + reference_moment_of_resistance = self.ref_moment_of_resistance(beam_length, ap_column_distance, force_per_ap_meter) + + while recalculated_moment_of_resistance < reference_moment_of_resistance: + recalculated_moment_of_resistance = self.recalculated_moment_of_resistance(start_height) + start_height += 0.01 + + moment_of_resistances.append(reference_moment_of_resistance) + heights.append(start_height) + lengths.append(beam_length) + + return heights, lengths + + +a = ProfileHeights(cross_section_type="hohlprofil", datum="l", width=50, thickness=2.5) + +ya_heights, xa_lengths = a.height_calculation() +plt.plot(xa_lengths, ya_heights) + +plt.xlabel("Länge des Trägers in mm") +plt.ylabel("Benötigte Querschnittshöhe des Trägers in mm") +plt.grid(True) +plt.show()