def __init__(self, forces_model, report, pinted=False): # You can do this in 5 lines. But this is readable. Deal with it ¬¬, try: if isinstance(forces_model, dict): self.use = forces_model['use'] if pinted: self.P = forces_model['P'] self.V2 = forces_model['V2'] self.V3 = forces_model['V3'] self.M2 = forces_model['M2'] self.M3 = forces_model['M3'] self.T = forces_model['T'] else: self.P = Q(D(forces_model['P']), 'kN') self.V2 = Q(D(forces_model['V2']), 'kN') self.V3 = Q(D(forces_model['V3']), 'kN') self.M2 = Q(D(forces_model['M2']), 'kN*m') self.M3 = Q(D(forces_model['M3']), 'kN*m') self.T = Q(D(forces_model['T']), 'kN*m') else: self.use = forces_model.use self.P = Q(forces_model.P, "kN") self.V2 = Q(forces_model.V2, "kN") self.V3 = Q(forces_model.V3, "kN") self.M2 = Q(forces_model.M2, "kN*m") self.M3 = Q(forces_model.M3, "kN*m") self.T = Q(forces_model.T, "kN*m") self.V = self.getV() self.M = self.getM() if report: self.reportSetup(report) except Exception as e: raise CalengCrash("Not a valid ForcesSet: " + str(e))
def sum_to_this_uls(self, forces, report): """ This method returns resultant forces, suming self.uls_forces with the given as positional argument """ try: top_V2 = self.top_uls * D(math.sin(self.top_ang)) top_P = self.top_uls * D(math.cos(self.top_ang)) bottom_V2 = -self.bottom_uls * D(math.sin(self.bottom_ang)) bottom_P = self.bottom_uls * D(math.cos(self.top_ang)) left_V3 = -self.left_uls * D(math.sin(self.left_ang)) left_P = self.left_uls * D(math.cos(self.left_ang)) right_V3 = self.right_uls * D(math.sin(self.right_ang)) right_P = self.right_uls * D(math.cos(self.right_ang)) P = forces.P + top_P + bottom_P + left_P + right_P V2 = forces.V2 + top_V2 + bottom_V2 V3 = forces.V3 + left_V3 + right_V3 # Future development: eccentricity in bracings. Will be needed to # update M2, M3 and T. For now this is enough. M2 = forces.M2 M3 = forces.M3 T = forces.T forces_dict = { 'use': "TOTAL ULS", 'P': P, 'V2': V2, 'V3': V3, 'M2': M2, 'M3': M3, 'T': T, } uls_forces = ForcesSet(forces_dict, report, pinted=True) except Exception as e: raise CalengCrash("Can't compute composed ULS resultant forces: " + str(e)) return uls_forces
def __init__(self, profile, dummy_bolted_plate, report): if profile.profile_type != "L": raise CalengCrash("Clip Angle must be a L Shaped Profile") self.profile_db_object = profile.get_mat_db_object() self.use = profile.use self.thickness = Q(self.profile_db_object.t, 'mm') self.locked_edges = [] self.width = Q(self.profile_db_object.b, 'mm') self.length = Q(self.profile_db_object.h, 'mm') if self.width != self.length: # To avoid this crash, a lot of shit must be reviewed. # S006 soolver sets ec1 = ec3. # A second bolt array must be added... f**k a lot of things. raise CalengCrash("Only simmetric L Clip Angle alowed") solve_from_steel_mat(self, profile.material) self.setup_e(dummy_bolted_plate, report) if report: self.reportSetup(report)
def bolt_the_flange(self, ba, bp, report): if self.profile_type == "H": pass elif self.profile_type == "U": pass else: raise CalengCrash("UNIMPLEMENTED BOLTED PROFILE " "DIFFERENT FROM H OR U") self.bolted_flange = BoltedFlange(self, ba, bp, report)
def getFv_Ed_max(self, forces, report): # Return if already computed hash_of_forces = hash(forces) + hash(self) if hash_of_forces in self.computed_Fv_Ed.keys(): return self.computed_Fv_Ed.get(hash_of_forces) desc_string = "SHEAR BOLT ARRAY: COMPUTING MAX SHEAR AT BOLTS"\ " | {}".format(forces.use) report.addLine(101, 20, desc_string, "") desc_string = "In plane shear distribution" calc_string = "n = " + str(self.n) report.addLine(100, 20, desc_string, calc_string) # If only one bolt, cant be torsion. Or crash. if not Q(D(-1), "N*mm") < forces.T < Q(D(1), "N*mm"): if self.n == 1: raise CalengCrash("One single bolt can't" " resist torsion forces!!") # else (T = 0), we dont need to compute anything else. else: Fv_Ed = (forces.V / self.n).to("kN") desc_string = "Max shear (no torsion)" calc_string = "Fv_Ed = " + str(Fv_Ed) report.addLine(100, 20, desc_string, calc_string) self.computed_Fv_Ed[hash_of_forces] = Fv_Ed return Fv_Ed sum_A_d2 = Q(D(0), "mm**4") max_A_d = Q(D(0), "mm**3") # Distribution of shear: shear_share for b in self.get_bolt_matrix(): if b[5] * self.bolt.A > max_A_d: max_A_d = b[5] * self.bolt.A sum_A_d2 += b[5]**2 * self.bolt.A desc_string = "Bolt " + str(b[0]) + ": row = " + str(b[1]) +\ ", col = " + str(b[2]) calc_string = "d = " + str(b[5]) report.addLine(100, 20, desc_string, calc_string) report.addLine(100, 20, "Total Inertia", "I = " + str(sum_A_d2)) shear_share = max_A_d / sum_A_d2 # Getting worst bolt Fv_Ed Fv_Ed_T = (forces.T * shear_share).to("kN") desc_string = "Max shear due to torsion" calc_string = "Fv_Ed_T = " + str(Fv_Ed_T) report.addLine(100, 20, desc_string, calc_string) Fv_Ed = (Fv_Ed_T + forces.V / self.n).to("kN") desc_string = "Max shear (including torsion)" calc_string = "Fv_Ed = " + str(Fv_Ed) report.addLine(100, 20, desc_string, calc_string) self.computed_Fv_Ed[hash_of_forces] = Fv_Ed return Fv_Ed
def check(self, sls_forces, uls_forces, report): if sls_forces.P.magnitude != 0 or sls_forces.M.magnitude != 0 \ or uls_forces.P.magnitude != 0 or uls_forces.M.magnitude != 0: raise CalengCrash("Not a ShearForcesSet provided" " to ShearBoltArray.check()") else: Fv_Ed_max_sls = self.getFv_Ed_max(sls_forces, report) Fv_Ed_max_uls = self.getFv_Ed_max(uls_forces, report) bolt_check = self.bolt.check(Q(0, "kN"), Fv_Ed_max_sls, Q(0, "kN"), Fv_Ed_max_uls, report) # Its needed to return de check status return bolt_check
def check(self, sls_forces, uls_forces, report): # If not shear forces, Crash. if sls_forces.T.magnitude != 0 or sls_forces.V.magnitude != 0 \ or uls_forces.T.magnitude != 0 or uls_forces.V.magnitude != 0: raise CalengCrash("Not a FrontForcesSet provided" " to TensionBoltArray.check()") else: Ft_Ed_max_sls = self.getFt_Ed_max(sls_forces, report) Ft_Ed_max_uls = self.getFt_Ed_max(uls_forces, report) bolt_check = self.bolt.check(Ft_Ed_max_sls, Q(0, "kN"), Ft_Ed_max_uls, Q(0, "kN"), report) return bolt_check
def solveFromSize(self, size_model): if isinstance(size_model, int): size_model = BoltSizeList.objects.get(id=int(size_model)) elif isinstance(size_model, str): size_model = BoltSizeList.objects.get(name=size_model) try: self.length = Q(size_model.length, "mm") self.diameter = Q(size_model.diameter, "mm") self.shaft_length = Q(size_model.shaft_length, "mm") self.A = Q(size_model.A, "mm**2") self.As = Q(size_model.As, "mm**2") self.dm = Q(size_model.dm, "mm") self.size_name = size_model.name if self.bolt_holes == "N": self.d0 = Q(size_model.hole, "mm") elif self.bolt_holes == "O": self.d0 = Q(size_model.os_hole, "mm") else: raise CalengCrash("Hole diameters are only defined for normal" " or oversized holes") except Exception as e: raise CalengCrash("Something happend when solving bolt parameters" " from provided bolt size. Exc: " + str(e))
def solveFromGrade(self, grade_model): if isinstance(grade_model, int): grade_model = BoltMaterialList.objects.get(id=int(grade_model)) elif isinstance(grade_model, str): grade_model = BoltMaterialList.objects.get(name=grade_model) try: self.fub = Q(grade_model.fub, "MPa") self.fyb = Q(grade_model.fyb, "MPa") self.Ym2 = D(1.25) if self.fub.magnitude < 401: self.Ym2 = D(1.50) self.E = Q(grade_model.E, "MPa") self.grade_name = grade_model.name except Exception as e: raise CalengCrash("Something happend when solving bolt parameters" " from provided bolt grade. Exc: " + str(e))
def __init__(self, t, fyd, bolt, e, m1, m2, rp): self.type = "Corner T-Stub" self.thickness = t self.fyd = fyd self.bolt = bolt self.e = e self.m1 = m1 self.m2 = m2 self.m = m1 self.n = min(e, D(1.25) * self.m) self.n1 = min(e, D(1.25) * m1) lambda1 = self.m1 / (self.m1 + self.e) lambda2 = self.m2 / (self.m1 + self.e) # This is ok! don't change try: self.alfa = Q(D(get_alfa(lambda1.magnitude, lambda2.magnitude))) except Exception as e: raise CalengCrash("Could not set tstub alfa: " + str(e)) self.leff = self.alfa * self.m
def solve_from_steel_mat(self, mat, report=None): try: if isinstance(mat, str): team = report.calc.user.profile.team q_object = Q_obj(team=team) | Q_obj(braced_builtin=True) steelmat = SteelMaterialList.objects.filter(q_object).get(name=mat) else: steelmat = mat self.fu = Q(D(steelmat.fu), "MPa") self.fy = Q(D(steelmat.fy), "MPa") self.Ym0 = D(1) # TO FIX MAYBE FROM DB I DONT KNOW self.Ym1 = D(1) # TO FIX MAYBE FROM DB I DONT KNOW self.Ym2 = D(1.25) # SAME self.E = Q(D(steelmat.E), "MPa") self.G = Q(D(steelmat.E), "MPa") self.material_name = steelmat.name except Exception as e: raise CalengCrash("Something happened when solving steel materials" " from provided material object. Exc: " + str(e))
def rot90(self, axis, times, use, report): """ axis is an integer 1,2,3. Times is an integer representing the number of times to 90 degree rotate in the direction of the axis. The comboname is a string to represent this new forces set """ forces = [self.P, self.V2, self.V3] moments = [self.T, self.M2, self.M3] for i in range(0, times): if axis == 1: forces = [forces[0], -forces[2], forces[1]] moments = [moments[0], -moments[2], moments[1]] elif axis == 2: forces = [forces[2], forces[1], -forces[0]] moments = [moments[2], moments[1], -moments[0]] elif axis == 3: forces = [-forces[1], forces[0], forces[2]] moments = [-moments[1], moments[0], moments[2]] else: forces = forces moments = moments raise CalengCrash("ForcesSet.rot90() needs an integer" " 1, 2 or 3.") if report: desc_string = "Generating rotated forces" report.addLine(100, 10, desc_string, use) # return rotated new object (all copied to avoid cagadas!) new_forces_set = copy(self) new_forces_set.P = copy(forces[0]) new_forces_set.V2 = copy(forces[1]) new_forces_set.V3 = copy(forces[2]) new_forces_set.T = copy(moments[0]) new_forces_set.M2 = copy(moments[1]) new_forces_set.M3 = copy(moments[2]) new_forces_set.V = new_forces_set.getV() new_forces_set.M = new_forces_set.getM() new_forces_set.use = use if report: new_forces_set.reportSetup(report) return new_forces_set
def __init__(self, t, fyd, bolt, e, e_other, m, bp, w, leff, rp): if t.magnitude == 0: raise CalengCrash("Plate thickness cant be 0") self.type = "Simple T-Stub" self.thickness = t self.fyd = fyd self.e = e self.m = m self.bolt = bolt self.n = min(e, D(1.25) * m) self.leff = min( D(4) * m + D(1.25) * e, e_other + D(2) * m + D(0.625) * e, D(0.5) * bp, D(0.5) * w + D(2) * m + D(0.625) * e, ) desc_string = "Single T Stub | Bolt " + str(bolt[0]) calc_string = "e={},m={},n={},leff={}"\ .format(self.e, self.m, self.n, self.leff) rp.addLine(100, 30, desc_string, calc_string)
def getFs_Rd(self, report): if not self.preloaded: raise CalengCrash("Can't get Fs_Rd in a snug tight bolt!") else: desc_string = "PRELOADED BOLT: SOLVING SLIP-RESISTANT CAPACITY" report.addLine(101, 20, desc_string, "") # solving Fs_Rd = (self.n * self.ks1 * self.mu * self.Fp_C / self.Ym3).to("kN") # reporting desc_string = "Preloaded bolt parameters" calc_string = "μ = " + str(self.mu) + ", ks = " + str(self.ks1) +\ ", Fp_C = " + str(self.Fp_C) report.addLine(100, 20, desc_string, calc_string) desc_string = "Max Slip-Resistant per-bolt capacity" calc_string = "Fs_Rd = " + str(Fs_Rd) report.addLine(100, 20, desc_string, calc_string) return Fs_Rd
def get_dist_list(string): try: elements = string.split() dist_list = [] for index, element in enumerate(elements): if "*" in element: times = element.split("*")[0] dist = element.split("*")[1] li = [dist] * int(times) dist_list.extend(li) else: dist_list.append(element) # Now we need to verify all data. A evil user can f**k us here # If something crashes we raise a message return_list = [] for item in dist_list: return_list.append(Q(D(item), "mm")) except Exception as e: raise CalengCrash("Crashed when parsing tekla notation distances: " + str(e)) return return_list
def __init__(self, model, report): try: if isinstance(model, dict): self.left_bracing = model['left_bracing'] self.right_bracing = model['right_bracing'] self.top_bracing = model['top_bracing'] self.bottom_bracing = model['bottom_bracing'] self.left_uls = Q(D(model['left_uls']), "kN") self.right_uls = Q(D(model['right_uls']), "kN") self.top_uls = Q(D(model['top_uls']), "kN") self.bottom_uls = Q(D(model['bottom_uls']), "kN") self.left_sls = Q(D(model['left_sls']), "kN") self.right_sls = Q(D(model['right_sls']), "kN") self.top_sls = Q(D(model['top_sls']), "kN") self.bottom_sls = Q(D(model['bottom_sls']), "kN") self.left_ang = Q(D(model['left_ang']), "degrees") self.right_ang = Q(D(model['right_ang']), "degrees") self.top_ang = Q(D(model['top_ang']), "degrees") self.bottom_ang = Q(D(model['bottom_ang']), "degrees") else: self.left_bracing = model.left_bracing self.right_bracing = model.right_bracing self.top_bracing = model.top_bracing self.bottom_bracing = model.bottom_bracing self.left_uls = Q(D(model.left_uls), "kN") self.right_uls = Q(D(model.right_uls), "kN") self.top_uls = Q(D(model.top_uls), "kN") self.bottom_uls = Q(D(model.bottom_uls), "kN") self.left_sls = Q(D(model.left_sls), "kN") self.right_sls = Q(D(model.right_sls), "kN") self.top_sls = Q(D(model.top_sls), "kN") self.bottom_sls = Q(D(model.bottom_sls), "kN") self.left_ang = Q(D(model.left_ang), "degrees") self.right_ang = Q(D(model.right_ang), "degrees") self.top_ang = Q(D(model.top_ang), "degrees") self.bottom_ang = Q(D(model.bottom_ang), "degrees") self.report_setup(report) except Exception as e: raise CalengCrash("Not a valid ExtraBracingForces: " + str(e))
def solve_from_polygons_legacy(plate, profile, position, bolt_array, report): """ Returns a list of tstub objects from given elements """ # usefull stuff t = plate.thickness fyd = plate.fy / plate.Ym0 bolts = bolt_array.get_bolt_matrix() tstub_list = [] # Get the profile positioned polygon rotated_pol = profile.get_polygon(report) # rotated_pol = affinity.rotate( # unpos_profile_pol, # float(position.rotation.magnitude), # origin=Point(0, 0)) profile_pol = affinity.translate(rotated_pol, xoff=-float(position.g1.magnitude), yoff=-float(position.g2.magnitude)) # Get the plate polygon plate_pol = plate.get_polygon(report) # Get the profile square boundary pb = profile_pol.bounds # Return void list if profile is 0 sized if len(pb) < 3: report.addLine(100, 30, "Empty profile. No TSTUB solved", "MANUAL REVIEW REQUIRED") return [] else: profile_boundary = Polygon(( (pb[2], pb[3]), (pb[2], pb[1]), (pb[0], pb[1]), (pb[0], pb[3]), )) if plate_pol.disjoint(profile_pol): raise CalengCrash("Profile boundary is outside plate!") # Outside plate and inside plate different tstub types out_plate = plate_pol.difference(profile_boundary) out_bolts = [] in_bolts = [] # Bolt data: (i, row, col, x1, x2, d, A, As) for bolt in bolts: point = Point(bolt[3].magnitude, bolt[4].magnitude) if point.within(out_plate): out_bolts.append(bolt) elif point.within(profile_boundary): in_bolts.append(bolt) else: print("Quizas este justo en el contorno. no?") raise CalengCrash("Problem at tstubs.solve_from_polygons()") # If profile is a pipe, we create SimpleTstub objects as if it were a tube # +---------+ +---------+ # | + | + | | 1 | 2 | <- We choose the worst m distance (biggest) # |---- ----| |---- ----| it may be in the 1 or 2 direction. # | | | | # |---- ----| |---- ----| # | + | + | | 3 | 4 | # +---------+ +---------+ # TUBE is the same shit if profile.profile_type == "PIP" or profile.profile_type == "TUB": for bolt in out_bolts: point = Point(bolt[3].magnitude, bolt[4].magnitude) # e = Q(D(point.distance(plate_pol.exterior)), "mm") e = plate.e2_main e_other = plate.e1_main bp = plate.width w = np.max(bolt_array.p1) m = Q(D(point.distance(profile_pol)), "mm") leff1 = plate.width / bolt_array.n1 leff2 = plate.length / bolt_array.n2 leff = min(leff1, leff2) args = (t, fyd, bolt, e, e_other, m, bp, w, leff, report) tstub = SimpleTStub(*args) tstub_list.append(tstub) # If profile is an H, we create SimpleTStub objects for the outter bolts # but we need to create CornerTStub objects for bolts between flanges # These bolts are into "in_bolts" list # +-----------+ +-----------+ # | + + | | 1 | 2 | <- We choose the worst m distance (biggest) # | _______ | |----- -----| it may be in the 1 or 2 direction. # | + | + | | 3 | 4 | <- 3 and 4 are CornerTstubs # | _______ | |----- -----| # | + + | | 5 | 6 | # +-----------+ +-----------+ # If profile is U: Same as H but with only one side with CornerTStubs # +-----------+ +-----------+ # | + + | | 1 | 2 | <- We choose the worst m distance (biggest) # | ____ | |----- -----| it may be in the 1 or 2 direction. # | + | + | | 3 | 4 | <- only 4 is a CornerTstubs # | ____ | |----- -----| # | + + | | 5 | 6 | # +-----------+ +-----------+ # If profile is L, same as U but may be a bug. else: # ELSE: Profile is H, U or L for bolt in out_bolts: point = Point(bolt[3].magnitude, bolt[4].magnitude) # e = Q(D(point.distance(plate_pol.exterior)), "mm") e = plate.e2_main e_other = plate.e1_main bp = plate.width w = np.max(bolt_array.p1) m = Q(D(point.distance(profile_pol)), "mm") leff1 = plate.width / bolt_array.n1 leff2 = plate.length / bolt_array.n2 leff = min(leff1, leff2) args = (t, fyd, bolt, e, e_other, m, bp, w, leff, report) tstub = SimpleTStub(*args) tstub_list.append(tstub) if profile.profile_type == "H": for bolt in in_bolts: point = Point(bolt[3].magnitude, bolt[4].magnitude) # Horizontal and vertical line from the point lpoint = affinity.translate(point, xoff=-1000) rpoint = affinity.translate(point, xoff=1000) dpoint = affinity.translate(point, yoff=-1000) upoint = affinity.translate(point, yoff=1000) horizontal_line = LineString([lpoint, rpoint]) vertical_line = LineString([dpoint, upoint]) # Points where the lines clashes with boundaries clash_h_pro = horizontal_line.intersection( profile_pol.exterior) clash_v_pro = vertical_line.intersection(profile_pol.exterior) clash_h_plate = horizontal_line.intersection( plate_pol.exterior) # Now, we need to find the closest point ¬¬' m1_adim = min(map(lambda x: point.distance(x), clash_h_pro)) m2_adim = min(map(lambda x: point.distance(x), clash_v_pro)) m1 = Q(D(m1_adim), "mm") m2 = Q(D(m2_adim), "mm") e_adim = min(map(lambda x: point.distance(x), clash_h_plate)) e = Q(D(e_adim), "mm") tstub_list.append(CornerTStub(t, fyd, bolt, e, m1, m2, report)) else: # ELSE: Profile is U or L for bolt in in_bolts: point = Point(bolt[3].magnitude, bolt[4].magnitude) # Let's go up! return tstub_list
def getFt_Ed_max_snug(self, forces, report): desc_string = "Snug-tight bolt group tension distribution" calc_string = "n = " + str(self.n) report.addLine(100, 20, desc_string, calc_string) if self.connected_plate is None: if forces.M2.magnitude != 0 and\ forces.M3.magnitude != 0: raise CalengCrash("TensionBoltArray needs a connected_plate" " if snug tight bolts.") else: return self.getFt_Ed_only_P(forces, report) if self.n2 == 1 and forces.M2.magnitude != 0: raise CalengCrash("Cant resist moments without lever arm") if self.connected_plate.length.magnitude == 0\ or self.connected_plate.width.magnitude == 0: raise CalengCrash("Plate must have a width and length") # Get forces due to M2 b = self.connected_plate.length h = self.connected_plate.width # Avoid 0 division p2_lev = self.p2_mean() if len( self.p2) > 0 else self.connected_plate.e2_main d = self.n1 * self.bolt.As / p2_lev c1 = (b - np.sqrt(d * b)) / (b - d) * h c = h - c1 I2 = d * c**3 / 3 + b * c1**3 / 3 desc_string = "Solving parameters for M2" report.addLine(100, 20, desc_string, "d = {}".format(str(d))) report.addLine(100, 20, "", "c1 = {}".format(str(c1))) report.addLine(100, 20, "", "c = {}".format(str(c))) report.addLine(100, 20, "", "I = {}".format(str(I2))) Ft_Ed_M2 = (forces.M2 * c * self.bolt.As / I2).to("kN") desc_string = "Max bolt tension due to joint M2" calc_string = "Ft_Ed_M2 = {}".format(str(Ft_Ed_M2)) report.addLine(100, 20, desc_string, calc_string) if self.n1 == 1 and forces.M3.magnitude != 0: raise CalengCrash("Cant resist moments without lever arm") # Get forces due to M3 b = self.connected_plate.width h = self.connected_plate.length # Avoid 0 division p1_lev = self.p1_mean() if len( self.p1) > 0 else self.connected_plate.e1_main d = self.n2 * self.bolt.As / p1_lev c1 = (b - np.sqrt(d * b)) / (b - d) * h c = h - c1 I3 = d * c**3 / 3 + b * c1**3 / 3 desc_string = "Solving parameters for M3" report.addLine(100, 20, desc_string, "d = {}".format(str(d))) report.addLine(100, 20, "", "c1 = {}".format(str(c1))) report.addLine(100, 20, "", "c = {}".format(str(c))) report.addLine(100, 20, "", "I = {}".format(str(I3))) Ft_Ed_M3 = (forces.M3 * c * self.bolt.As / I3).to("kN") desc_string = "Max bolt tension due to joint M3" calc_string = "Ft_Ed_M3 = {}".format(str(Ft_Ed_M3)) report.addLine(100, 20, desc_string, calc_string) # Get forces due to P Ft_Ed_P = (forces.P / self.n).to("kN") desc_string = "Max bolt tension due to joint tension" calc_string = "Ft_Ed_P = {}".format(str(Ft_Ed_P)) report.addLine(100, 20, desc_string, calc_string) # Returning solution Ft_Ed = Ft_Ed_P + Ft_Ed_M2 + Ft_Ed_M3 desc_string = "Max bolt tension" calc_string = "Ft_Ed = " + str(Ft_Ed) report.addLine(100, 20, desc_string, calc_string) return Ft_Ed