| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| |
|
| | import FreeCAD, FreeCADGui |
| | from .SegmentFunction import SegmentFunction, IntervalFunction, StressFunction, TranslationFunction |
| | from .ShaftFeature import ShaftFeature |
| | from .ShaftDiagram import Diagram |
| | import math |
| |
|
| |
|
| | class ShaftSegment: |
| | def __init__(self, l, d, di): |
| | self.length = l |
| | self.diameter = d |
| | self.innerdiameter = di |
| | self.constraintType = "None" |
| | self.constraint = None |
| |
|
| |
|
| | class Shaft: |
| | "The axis of the shaft is always assumed to correspond to the X-axis" |
| |
|
| | |
| | Fstr = ["Nx", "Qy", "Qz"] |
| | Mstr = ["Mx", "Mz", "My"] |
| | wstr = ["", "wy", "wz"] |
| | sigmaNstr = ["sigmax", "sigmay", "sigmaz"] |
| | sigmaBstr = ["taut", "sigmabz", "sigmaby"] |
| | |
| | Qstrings = ( |
| | ("Normal force [x]", "x", "mm", "N_x", "N"), |
| | ("Shear force [y]", "x", "mm", "Q_y", "N"), |
| | ("Shear force [z]", "x", "mm", "Q_z", "N"), |
| | ) |
| | Mstrings = ( |
| | ("Torque [x]", "x", "mm", "M_t", "Nm"), |
| | ("Bending moment [z]", "x", "mm", "M_{b,z}", "Nm"), |
| | ("Bending moment [y]", "x", "mm", "M_{b,y}", "Nm"), |
| | ) |
| | wstrings = ( |
| | ("", "", "", "", ""), |
| | ("Translation [y]", "x", "mm", "w_y", "mm"), |
| | ("Translation [z]", "x", "mm", "w_z", "mm"), |
| | ) |
| | sigmaNstrings = ( |
| | ("Normal stress [x]", "x", "mm", "\\sigma_x", "N/mm²"), |
| | ("Shear stress [y]", "x", "mm", "\\sigma_y", "N/mm²"), |
| | ("Shear stress [z]", "x", "mm", "\\sigma_z", "N/mm²"), |
| | ) |
| | sigmaBstrings = ( |
| | ("Torque stress [x]", "x", "mm", "\\tau_t", "N/mm²"), |
| | ("Bending stress [z]", "x", "mm", "\\sigma_{b,z}", "N/mm²"), |
| | ("Bending stress [y]", "x", "mm", "\\sigma_{b,y}", "N/mm²"), |
| | ) |
| |
|
| | def __init__(self, parent): |
| | self.parent = parent |
| | self.doc = parent.doc |
| | self.feature = ShaftFeature(self.doc) |
| | |
| | self.segments = [] |
| | |
| | self.diagrams = {} |
| | |
| | self.F = [None, None, None] |
| | self.M = [None, None, None] |
| | self.w = [None, None, None] |
| | self.sigmaN = [ |
| | None, |
| | None, |
| | None, |
| | ] |
| | self.sigmaB = [ |
| | None, |
| | None, |
| | None, |
| | ] |
| |
|
| | def getLengthTo(self, index): |
| | "Get the total length of all segments up to the given one" |
| | result = 0.0 |
| | for i in range(index): |
| | result += self.segments[i].length |
| | return result |
| |
|
| | def addSegment(self, l, d, di): |
| | self.segments.append(ShaftSegment(l, d, di)) |
| | self.feature.addSegment(l, d, di) |
| | |
| | |
| | for i in range(1, len(self.segments)): |
| | if self.segments[i].constraintType != "Fixed": |
| | continue |
| | if i == len(self.segments) - 1: |
| | self.segments[index].constraint.References = [ |
| | (self.feature.feature, "Face%u" % (2 * (index + 1) + 1)) |
| | ] |
| | else: |
| | |
| | self.segments[index].constraint.References = [(None, "")] |
| |
|
| | def updateSegment(self, index, length=None, diameter=None, innerdiameter=None): |
| | oldLength = self.segments[index].length |
| |
|
| | if length is not None: |
| | self.segments[index].length = length |
| | if diameter is not None: |
| | self.segments[index].diameter = diameter |
| | if innerdiameter is not None: |
| | self.segments[index].innerdiameter = innerdiameter |
| |
|
| | self.feature.updateSegment( |
| | index, |
| | oldLength, |
| | self.segments[index].length, |
| | self.segments[index].diameter, |
| | self.segments[index].innerdiameter, |
| | ) |
| | self.equilibrium() |
| | self.updateDiagrams() |
| |
|
| | def updateConstraint(self, index, constraintType): |
| | if constraintType is not None: |
| | |
| | if (self.segments[index].constraintType != "None") and ( |
| | self.segments[index].constraintType != constraintType |
| | ): |
| | self.doc.removeObject(self.segments[index].constraint.Name) |
| | self.segments[index].constraint = None |
| |
|
| | self.segments[index].constraintType = constraintType |
| |
|
| | |
| | if self.segments[index].constraint is None: |
| | if constraintType == "Force": |
| | |
| | constraint = self.doc.addObject("Fem::ConstraintForce", "ShaftConstraintForce") |
| | constraint.Force = 1000.0 |
| | self.segments[index].constraint = constraint |
| | elif constraintType == "Fixed": |
| | |
| | constraint = self.doc.addObject("Fem::ConstraintFixed", "ShaftConstraintFixed") |
| | if index == 0: |
| | constraint.References = [(self.feature.feature, "Face1")] |
| | elif index == len(self.segments) - 1: |
| | constraint.References = [ |
| | (self.feature.feature, "Face%u" % (2 * (index + 1) + 1)) |
| | ] |
| | self.segments[index].constraint = constraint |
| | elif constraintType == "Bearing": |
| | |
| | constraint = self.doc.addObject( |
| | "Fem::ConstraintBearing", "ShaftConstraintBearing" |
| | ) |
| | constraint.References = [(self.feature.feature, "Face%u" % (2 * (index + 1)))] |
| | constraint.AxialFree = True |
| | self.segments[index].constraint = constraint |
| | elif constraintType == "Pulley": |
| | constraint = self.doc.addObject( |
| | "Fem::ConstraintPulley", "ShaftConstraintPulley" |
| | ) |
| | constraint.References = [(self.feature.feature, "Face%u" % (2 * (index + 1)))] |
| | self.segments[index].constraint = constraint |
| | elif constraintType == "Gear": |
| | constraint = self.doc.addObject("Fem::ConstraintGear", "ShaftConstraintGear") |
| | constraint.References = [(self.feature.feature, "Face%u" % (2 * (index + 1)))] |
| | self.segments[index].constraint = constraint |
| |
|
| | self.equilibrium() |
| | self.updateDiagrams() |
| |
|
| | def editConstraint(self, index): |
| | if self.segments[index].constraint is not None: |
| | FreeCADGui.activeDocument().setEdit(self.segments[index].constraint.Name) |
| |
|
| | def getConstraint(self, index): |
| | return self.segments[index].constraint |
| |
|
| | def updateEdge(self, column, start): |
| | App.Console.PrintMessage("Not implemented yet - waiting for robust references…") |
| | return |
| | """ |
| | if self.sketchClosed is not True: |
| | return |
| | # Create a chamfer or fillet at the start or end edge of the segment |
| | if start is True: |
| | row = rowStartEdgeType |
| | idx = 0 |
| | else: |
| | row = rowEndEdgeType |
| | idx = 1 |
| | |
| | edgeType = self.tableWidget.item(row, column).text()[0].upper() |
| | if not ((edgeType == "C") or (edgeType == "F")): |
| | return # neither chamfer nor fillet defined |
| | |
| | if edgeType == "C": |
| | objName = self.doc.addObject("PartDesign::Chamfer","ChamferShaft%u" % (column * 2 + idx)) |
| | else: |
| | objName = self.doc.addObject("PartDesign::Fillet","FilletShaft%u" % (column * 2 + idx)) |
| | if objName == "": |
| | return |
| | |
| | edgeName = "Edge%u" % self.getEdgeIndex(column, idx, edgeType) |
| | self.doc.getObject(objName).Base = (self.doc.getObject("RevolutionShaft"),"[%s]" % edgeName) |
| | # etc. etc. |
| | """ |
| |
|
| | def getEdgeIndex(self, column, startIdx): |
| | |
| | return |
| |
|
| | def updateDiagrams(self): |
| | for ax in range(3): |
| | if self.F[ax] is not None: |
| | if self.F[ax].name in self.diagrams: |
| | self.diagrams[self.F[ax].name].update( |
| | self.F[ax], self.getLengthTo(len(self.segments)) / 1000.0 |
| | ) |
| | if self.M[ax] is not None: |
| | if self.M[ax].name in self.diagrams: |
| | self.diagrams[self.M[ax].name].update( |
| | self.M[ax], self.getLengthTo(len(self.segments)) / 1000.0 |
| | ) |
| | if self.w[ax] is not None: |
| | if self.w[ax].name in self.diagrams: |
| | self.diagrams[self.w[ax].name].update( |
| | self.w[ax], self.getLengthTo(len(self.segments)) / 1000.0 |
| | ) |
| | if self.sigmaN[ax] is not None: |
| | if self.sigmaN[ax].name in self.diagrams: |
| | self.diagrams[self.sigmaN[ax].name].update( |
| | self.sigmaN[ax], self.getLengthTo(len(self.segments)) / 1000.0 |
| | ) |
| | if self.sigmaB[ax] is not None: |
| | if self.sigmaB[ax].name in self.diagrams: |
| | self.diagrams[self.sigmaB[ax].name].update( |
| | self.sigmaB[ax], self.getLengthTo(len(self.segments)) / 1000.0 |
| | ) |
| |
|
| | def showDiagram(self, which): |
| | if which in self.Fstr: |
| | ax = self.Fstr.index(which) |
| | text = self.Qstrings[ax] |
| | if self.F[ax] is None: |
| | |
| | return |
| | if self.F[ax].name in self.diagrams: |
| | |
| | self.diagrams[self.F[ax].name].close() |
| | del self.diagrams[self.F[ax].name] |
| | return |
| | self.diagrams[self.F[ax].name] = Diagram() |
| | self.diagrams[self.F[ax].name].create( |
| | text[0], |
| | self.F[ax], |
| | self.getLengthTo(len(self.segments)) / 1000.0, |
| | text[1], |
| | text[2], |
| | 1000.0, |
| | text[3], |
| | text[4], |
| | 1.0, |
| | 10, |
| | ) |
| | elif which in self.Mstr: |
| | ax = self.Mstr.index(which) |
| | text = self.Mstrings[ax] |
| | if self.M[ax] is None: |
| | |
| | return |
| | if self.M[ax].name in self.diagrams: |
| | |
| | self.diagrams[self.M[ax].name].close() |
| | del self.diagrams[self.M[ax].name] |
| | return |
| | self.diagrams[self.M[ax].name] = Diagram() |
| | self.diagrams[self.M[ax].name].create( |
| | text[0], |
| | self.M[ax], |
| | self.getLengthTo(len(self.segments)) / 1000.0, |
| | text[1], |
| | text[2], |
| | 1000.0, |
| | text[3], |
| | text[4], |
| | 1.0, |
| | 20, |
| | ) |
| | elif which in self.wstr: |
| | ax = self.wstr.index(which) |
| | text = self.wstrings[ax] |
| | if self.w[ax] is None: |
| | |
| | return |
| | if self.w[ax].name in self.diagrams: |
| | |
| | self.diagrams[self.w[ax].name].close() |
| | del self.diagrams[self.w[ax].name] |
| | return |
| | self.diagrams[self.w[ax].name] = Diagram() |
| | self.diagrams[self.w[ax].name].create( |
| | text[0], |
| | self.w[ax], |
| | self.getLengthTo(len(self.segments)) / 1000.0, |
| | text[1], |
| | text[2], |
| | 1000.0, |
| | text[3], |
| | text[4], |
| | 1000.0, |
| | 30, |
| | ) |
| | elif which in self.sigmaNstr: |
| | ax = self.sigmaNstr.index(which) |
| | text = self.sigmaNstrings[ax] |
| | if self.sigmaN[ax] is None: |
| | |
| | return |
| | if self.sigmaN[ax].name in self.diagrams: |
| | |
| | self.diagrams[self.sigmaN[ax].name].close() |
| | del self.diagrams[self.sigmaN[ax].name] |
| | return |
| | self.diagrams[self.sigmaN[ax].name] = Diagram() |
| | self.diagrams[self.sigmaN[ax].name].create( |
| | text[0], |
| | self.sigmaN[ax], |
| | self.getLengthTo(len(self.segments)) / 1000.0, |
| | text[1], |
| | text[2], |
| | 1000.0, |
| | text[3], |
| | text[4], |
| | 1.0e-6, |
| | 10, |
| | ) |
| | elif which in self.sigmaBstr: |
| | ax = self.sigmaBstr.index(which) |
| | text = self.sigmaBstrings[ax] |
| | if self.sigmaB[ax] is None: |
| | |
| | return |
| | if self.sigmaB[ax].name in self.diagrams: |
| | |
| | self.diagrams[self.sigmaB[ax].name].close() |
| | del self.diagrams[self.sigmaB[ax].name] |
| | return |
| | self.diagrams[self.sigmaB[ax].name] = Diagram() |
| | self.diagrams[self.sigmaB[ax].name].create( |
| | text[0], |
| | self.sigmaB[ax], |
| | self.getLengthTo(len(self.segments)) / 1000.0, |
| | text[1], |
| | text[2], |
| | 1000.0, |
| | text[3], |
| | text[4], |
| | 1.0e-6, |
| | 20, |
| | ) |
| |
|
| | def addTo(self, dict, location, value): |
| | if location not in dict: |
| | dict[location] = value |
| | else: |
| | dict[location] += value |
| |
|
| | def equilibrium(self): |
| | |
| | try: |
| | import numpy as np |
| | except ImportError: |
| | FreeCAD.Console.PrintMessage("numpy is not installed on your system\n") |
| | raise ImportError("numpy not installed") |
| |
|
| | |
| | |
| | |
| | |
| | |
| | forces = [{0.0: 0.0}, {0.0: 0.0}, {0.0: 0.0}] |
| | moments = [{0.0: 0.0}, {0.0: 0.0}, {0.0: 0.0}] |
| | |
| | tangents = [[], [], []] |
| | translations = [[], [], []] |
| | |
| | |
| | variableNames = [[""], [""], [""]] |
| | |
| | locations = {} |
| | |
| | |
| | coefficientsF = [[0], [0], [0]] |
| | coefficientsM = [[0], [0], [0]] |
| |
|
| | for i in range(len(self.segments)): |
| | cType = self.segments[i].constraintType |
| | constraint = self.segments[i].constraint |
| |
|
| | if cType == "Fixed": |
| | |
| | if i == 0: |
| | |
| | location = 0 |
| | elif i == len(self.segments) - 1: |
| | |
| | location = self.getLengthTo(len(self.segments)) / 1000.0 |
| | else: |
| | |
| | FreeCAD.Console.PrintMessage( |
| | "Fixed constraint must be at beginning or end of shaft\n" |
| | ) |
| | return |
| |
|
| | for ax in range(3): |
| | |
| | variableNames[ax].append("%s%u" % (self.Fstr[ax], i)) |
| | coefficientsF[ax].append(1) |
| | |
| | locations["%s%u" % (self.Fstr[ax], i)] = location |
| | |
| | tangents[ax].append((location, 0.0)) |
| | translations[ax].append((location, 0.0)) |
| | coefficientsM[0].append(0) |
| | coefficientsM[1].append( |
| | location |
| | ) |
| | coefficientsM[2].append( |
| | -location |
| | ) |
| |
|
| | for ax in range(3): |
| | |
| | variableNames[ax].append("%s%u" % (self.Mstr[ax], i)) |
| | coefficientsF[ax].append(0) |
| | coefficientsM[ax].append(1) |
| | locations["%s%u" % (self.Mstr[ax], i)] = location |
| |
|
| | elif cType == "Force": |
| | |
| | force = constraint.DirectionVector.multiply(constraint.Force) |
| | |
| | location = (self.getLengthTo(i) + self.segments[i].length / 2.0) / 1000.0 |
| | |
| | for ax in range(3): |
| | if abs(force[ax]) > 0.0: |
| | coefficientsF[ax][0] = ( |
| | coefficientsF[ax][0] - force[ax] |
| | ) |
| | self.addTo( |
| | forces[ax], location, -force[ax] |
| | ) |
| | |
| | if abs(force[1]) > 0.0: |
| | coefficientsM[1][0] = ( |
| | coefficientsM[1][0] - force[1] * location |
| | ) |
| | self.addTo(moments[1], location, 0) |
| | if abs(force[2]) > 0.0: |
| | coefficientsM[2][0] = ( |
| | coefficientsM[2][0] + force[2] * location |
| | ) |
| | self.addTo(moments[2], location, 0) |
| |
|
| | elif cType == "Bearing": |
| | location = ( |
| | constraint.BasePoint.x / 1000.0 |
| | ) |
| | |
| | start = 0 if constraint.AxialFree == False else 1 |
| | for ax in range(start, 3): |
| | variableNames[ax].append("%s%u" % (self.Fstr[ax], i)) |
| | coefficientsF[ax].append(1) |
| | locations["%s%u" % (self.Fstr[ax], i)] = location |
| | |
| | translations[ax].append((location, 0.0)) |
| | if constraint.AxialFree == False: |
| | coefficientsM[0].append(0) |
| | coefficientsM[1].append( |
| | location |
| | ) |
| | coefficientsM[2].append( |
| | -location |
| | ) |
| |
|
| | elif cType == "Gear": |
| | force = constraint.DirectionVector.multiply(constraint.Force) |
| | location = constraint.BasePoint.x / 1000.0 |
| | lever = [ |
| | 0, |
| | constraint.Diameter |
| | / 2.0 |
| | / 1000.0 |
| | * math.sin(constraint.ForceAngle / 180.0 * math.pi), |
| | constraint.Diameter |
| | / 2.0 |
| | / 1000.0 |
| | * math.cos(constraint.ForceAngle / 180.0 * math.pi), |
| | ] |
| |
|
| | |
| | for ax in range(3): |
| | if abs(force[ax]) > 0.0: |
| | |
| | coefficientsF[ax][0] = coefficientsF[ax][0] - force[ax] |
| | self.addTo(forces[ax], location, -force[ax]) |
| | |
| | if abs(force[1]) > 0.0: |
| | coefficientsM[1][0] = ( |
| | coefficientsM[1][0] - force[1] * location |
| | ) |
| | self.addTo(moments[1], location, 0) |
| | if abs(force[2]) > 0.0: |
| | coefficientsM[2][0] = ( |
| | coefficientsM[2][0] + force[2] * location |
| | ) |
| | self.addTo(moments[2], location, 0) |
| |
|
| | |
| | if abs(force[0]) > 0.0: |
| | momenty = force[0] * lever[2] |
| | momentz = force[0] * lever[1] |
| | coefficientsM[1][0] = coefficientsM[1][0] + momentz |
| | self.addTo(moments[1], location, momentz) |
| | coefficientsM[2][0] = coefficientsM[2][0] - momenty |
| | self.addTo(moments[2], location, -momenty) |
| | if abs(force[1]) > 0.0: |
| | moment = force[1] * lever[2] |
| | coefficientsM[0][0] = coefficientsM[0][0] + moment |
| | self.addTo(moments[0], location, moment) |
| | if abs(force[2]) > 0.0: |
| | moment = force[2] * lever[1] |
| | coefficientsM[0][0] = coefficientsM[0][0] - moment |
| | self.addTo(moments[0], location, -moment) |
| | elif cType == "Pulley": |
| | forceAngle1 = ( |
| | (constraint.ForceAngle + constraint.BeltAngle + 90.0) / 180.0 * math.pi |
| | ) |
| | forceAngle2 = ( |
| | (constraint.ForceAngle - constraint.BeltAngle + 90.0) / 180.0 * math.pi |
| | ) |
| | |
| | |
| | force = [ |
| | 0, |
| | -constraint.BeltForce1 * math.sin(forceAngle1) |
| | - constraint.BeltForce2 * math.sin(forceAngle2), |
| | constraint.BeltForce1 * math.cos(forceAngle1) |
| | + constraint.BeltForce2 * math.cos(forceAngle2), |
| | ] |
| | location = constraint.BasePoint.x / 1000.0 |
| |
|
| | |
| | for ax in range(3): |
| | if abs(force[ax]) > 0.0: |
| | |
| | coefficientsF[ax][0] = coefficientsF[ax][0] - force[ax] |
| | self.addTo(forces[ax], location, -force[ax]) |
| | |
| | if abs(force[1]) > 0.0: |
| | coefficientsM[1][0] = ( |
| | coefficientsM[1][0] - force[1] * location |
| | ) |
| | self.addTo(moments[1], location, 0) |
| | if abs(force[2]) > 0.0: |
| | coefficientsM[2][0] = ( |
| | coefficientsM[2][0] + force[2] * location |
| | ) |
| | self.addTo(moments[2], location, 0) |
| |
|
| | |
| | moment = constraint.Force * (1 if constraint.IsDriven is True else -1) |
| | coefficientsM[0][0] = coefficientsM[0][0] + moment |
| | self.addTo(moments[0], location, moment) |
| |
|
| | areas = [None, None, None] |
| | areamoments = [None, None, None] |
| | bendingmoments = [None, None, None] |
| | torquemoments = [None, None, None] |
| |
|
| | for ax in range(3): |
| | FreeCAD.Console.PrintMessage("Axis: %u\n" % ax) |
| | self.printEquilibrium(variableNames[ax], coefficientsF[ax]) |
| | self.printEquilibrium(variableNames[ax], coefficientsM[ax]) |
| |
|
| | if len(coefficientsF[ax]) <= 1: |
| | |
| | FreeCAD.Console.PrintMessage("Matrix is singular, no solution possible\n") |
| | self.parent.updateButtons(ax, False) |
| | continue |
| |
|
| | |
| | solution = [None, None] |
| | if len(coefficientsF[ax]) == 2: |
| | if coefficientsF[ax][1] != 0.0 and coefficientsF[ax][0] != 0.0: |
| | solution[0] = coefficientsF[ax][0] / coefficientsF[ax][1] |
| | if coefficientsM[ax][1] != 0.0 and coefficientsM[ax][0] != 0.0: |
| | solution[1] = coefficientsM[ax][0] / coefficientsM[ax][1] |
| | if abs(solution[0] - solution[1]) < 1e9: |
| | FreeCAD.Console.PrintMessage( |
| | "System is statically undetermined. No solution possible.\n" |
| | ) |
| | self.parent.updateButtons(ax, False) |
| | continue |
| | else: |
| | |
| | |
| | A = np.array([coefficientsF[ax][1:], coefficientsM[ax][1:]]) |
| | b = np.array([coefficientsF[ax][0], coefficientsM[ax][0]]) |
| | try: |
| | solution = np.linalg.solve(A, b) |
| | except np.linalg.linalg.LinAlgError as e: |
| | FreeCAD.Console.PrintMessage(str(e)) |
| | FreeCAD.Console.PrintMessage(". No solution possible.\n") |
| | self.parent.updateButtons(ax, False) |
| | continue |
| |
|
| | |
| | for i in range(2): |
| | if solution[i] is None: |
| | continue |
| | FreeCAD.Console.PrintMessage( |
| | "Reaction force/moment: %s = %f\n" % (variableNames[ax][i + 1], solution[i]) |
| | ) |
| | if variableNames[ax][i + 1][0] == "M": |
| | moments[ax][locations[variableNames[ax][i + 1]]] = -solution[i] |
| | else: |
| | forces[ax][locations[variableNames[ax][i + 1]]] = -solution[i] |
| |
|
| | FreeCAD.Console.PrintMessage(forces[ax]) |
| | FreeCAD.Console.PrintMessage("\n") |
| | FreeCAD.Console.PrintMessage(moments[ax]) |
| | FreeCAD.Console.PrintMessage("\n") |
| |
|
| | |
| | self.F[ax] = SegmentFunction(self.Fstr[ax]) |
| | self.F[ax].buildFromDict("x", forces[ax]) |
| | self.parent.updateButton(1, ax, not self.F[ax].isZero()) |
| | self.F[ax].output() |
| | |
| | if ax == 0: |
| | self.M[0] = SegmentFunction(self.Mstr[0]) |
| | self.M[0].buildFromDict("x", moments[0]) |
| | elif ax == 1: |
| | self.M[1] = self.F[1].integrated().negate() |
| | self.M[1].name = self.Mstr[1] |
| | self.M[1].addSegments(moments[1]) |
| | elif ax == 2: |
| | self.M[2] = self.F[2].integrated() |
| | self.M[2].name = self.Mstr[2] |
| | self.M[2].addSegments(moments[2]) |
| | self.parent.updateButton(2, ax, not self.M[ax].isZero()) |
| | self.M[ax].output() |
| |
|
| | |
| | location = 0.0 |
| | areas[ax] = IntervalFunction() |
| | areamoments[ax] = IntervalFunction() |
| | bendingmoments[ax] = IntervalFunction() |
| | torquemoments[ax] = IntervalFunction() |
| |
|
| | for i in range(len(self.segments)): |
| | od = self.segments[i].diameter / 1000.0 |
| | id = self.segments[i].innerdiameter / 1000.0 |
| | length = self.segments[i].length / 1000.0 |
| | areas[ax].addInterval( |
| | location, length, math.pi / 4.0 * (math.pow(od, 2.0) - math.pow(id, 2.0)) |
| | ) |
| | areamoment = math.pi / 64.0 * (math.pow(od, 4.0) - math.pow(id, 4.0)) |
| | areamoments[ax].addInterval(location, length, areamoment) |
| | bendingmoments[ax].addInterval(location, length, areamoment / (od / 2.0)) |
| | torquemoments[ax].addInterval(location, length, 2 * (areamoment / (od / 2.0))) |
| | location += length |
| |
|
| | |
| | if ax > 0: |
| | if len(tangents[ax]) + len(translations[ax]) == 2: |
| | |
| | self.w[ax] = TranslationFunction( |
| | self.M[ax].negated(), |
| | 2.1e12, |
| | areamoments[ax], |
| | tangents[ax], |
| | translations[ax], |
| | ) |
| | self.w[ax].name = self.wstr[ax] |
| | self.parent.updateButton(3, ax, not self.w[ax].isZero()) |
| | else: |
| | self.parent.updateButton(3, ax, False) |
| |
|
| | |
| | self.sigmaN[ax] = StressFunction(self.F[ax], areas[ax]) |
| | self.sigmaN[ax].name = self.sigmaNstr[ax] |
| | self.parent.updateButton(4, ax, not self.sigmaN[ax].isZero()) |
| | if ax == 0: |
| | self.sigmaB[ax] = StressFunction(self.M[ax], torquemoments[ax]) |
| | else: |
| | self.sigmaB[ax] = StressFunction(self.M[ax], bendingmoments[ax]) |
| | self.sigmaB[ax].name = self.sigmaBstr[ax] |
| | self.parent.updateButton(5, ax, not self.sigmaB[ax].isZero()) |
| |
|
| | def printEquilibrium(self, var, coeff): |
| | |
| | for i in range(len(var)): |
| | if i == 0: |
| | FreeCAD.Console.PrintMessage("%f = " % coeff[i]) |
| | else: |
| | FreeCAD.Console.PrintMessage("%f * %s" % (coeff[i], var[i])) |
| | if (i < len(var) - 1) and (i != 0): |
| | FreeCAD.Console.PrintMessage(" + ") |
| | FreeCAD.Console.PrintMessage("\n") |
| |
|