def test_utils_single(self): expected = 1 single = [expected] result = getAbsMax(single) test = result == expected assert test
def test_utils_negative(self): expected = 10 uniform = [-1, -2, -3, -expected, -4] result = getAbsMax(uniform) test = result == expected assert test
def test_utils_positive(self): expected = 10 uniform = [1, 2, 3, expected, 4] result = getAbsMax(uniform) test = result == expected assert test
def test_utils_uniform(self): expected = 1 uniform = [] for _i in range(10): uniform.append(expected) result = getAbsMax(uniform) test = result == expected assert test
def runAnalysis(self, n=10**3, showPlots=True, outputToFile=False): """ `n` - optional number of data points to run the analysis, default is 10^3 """ pre = "[BEAM ANALYSIS] - " print(f"{pre}Running analysis with beam parameters:") bL = "length:" bE = "Young's modulus of material:" bI = "Moment of inertia:" print(f"{pre}{bL:30} {self.L}") print(f"{pre}{bE:30} {self.E}") print(f"{pre}{bI:30} {self.I}") # =================================== # # = Solve for Singularity Constants = * # =================================== # self.SingularityXY.solve() xySingularities = [ self.SingularityXY.getString(BeamAnalysisTypes.SHEAR), self.SingularityXY.getString(BeamAnalysisTypes.BENDING), self.SingularityXY.getString(BeamAnalysisTypes.ANGLE), self.SingularityXY.getString(BeamAnalysisTypes.DEFLECTION) ] self.SingularityXZ.solve() xzSingularities = [ self.SingularityXZ.getString(BeamAnalysisTypes.SHEAR), self.SingularityXZ.getString(BeamAnalysisTypes.BENDING), self.SingularityXZ.getString(BeamAnalysisTypes.ANGLE), self.SingularityXZ.getString(BeamAnalysisTypes.DEFLECTION) ] # determine if there is any anlaysis to run hasXY = not all(s == "" for s in xySingularities) hasXZ = not all(s == "" for s in xzSingularities) if not (hasXY or hasXZ): print("No analysis available in XY or XZ.") print("Quitting...") quit() # =================================== # # ========== Beam Results =========== # # =================================== # xVals = np.linspace(0, self.L, n) xyShear, xyBending, xyAngle, xyDeflection = [], [], [], [] xzShear, xzBending, xzAngle, xzDeflection = [], [], [], [] for x in xVals: xyShear.append(self.SingularityXY.evaluateAt(x, BeamAnalysisTypes.SHEAR)) xyBending.append(self.SingularityXY.evaluateAt(x, BeamAnalysisTypes.BENDING)) xyAngle.append(self.SingularityXY.evaluateAt(x, BeamAnalysisTypes.ANGLE)) xyDeflection.append(self.SingularityXY.evaluateAt(x, BeamAnalysisTypes.DEFLECTION)) xzShear.append(self.SingularityXZ.evaluateAt(x, BeamAnalysisTypes.SHEAR)) xzBending.append(self.SingularityXZ.evaluateAt(x, BeamAnalysisTypes.BENDING)) xzAngle.append(self.SingularityXZ.evaluateAt(x, BeamAnalysisTypes.ANGLE)) xzDeflection.append(self.SingularityXZ.evaluateAt(x, BeamAnalysisTypes.DEFLECTION)) # =================================== # # ============= Report ============== # # =================================== # pre_solving = "[SOLVING] - " mS = "Max Shear:" mM = "Max Moment:" mA = "Max Angle:" mD = "Max Deflection:" sep = f"# {'='*max(len(xySingularities[3]), len(xzSingularities[3]))} #" # digits to round to rdSh = 3 rdB = 3 rdA = 5 rdD = 5 # write singularity constants in XY to console if hasXY: print(sep) print(f"{pre}{pre_solving}Solved for xy angle constant C1 = {self.SingularityXY.C1}") print(f"{pre}{pre_solving}Solved for xy deflection constant C2 = {self.SingularityXY.C2}") # write singularity constants in XZ to console if hasXZ: print(sep) print(f"{pre}{pre_solving}Solved for xz angle constant C1 = {self.SingularityXZ.C1}") print(f"{pre}{pre_solving}Solved for xz deflection constant C2 = {self.SingularityXZ.C2}") # write singularities in XY to console if hasXY: print(sep) print(f"{pre}Singularity functions in XY:") for s in xySingularities: print(s) # write singularities in XZ to console if hasXZ: print(sep) print(f"{pre}Singularity functions in XZ:") for s in xzSingularities: print(s) # write max vals in XY to console if hasXY: mSxy = utils.getAbsMax(xyShear, rdSh) mBxy = utils.getAbsMax(xyBending, rdB) mAxy = utils.getAbsMax(xyAngle, rdA) mDxy = utils.getAbsMax(xyDeflection, rdD) print(sep) print(f"{pre}Report in XY:") print(f"{mS:20} {mSxy:10} {self.ShearUnits.Label}") print(f"{mM:20} {mBxy:10} {self.MomentUnits.Label}") print(f"{mA:20} {mAxy:10} {self.AngleUnits.Label}") print(f"{mD:20} {mDxy:10} {self.DeflectionUnits.Label}") # write max vals in XZ to console if hasXZ: mSxz = utils.getAbsMax(xzShear, rdSh) mBxz = utils.getAbsMax(xzBending, rdB) mAxz = utils.getAbsMax(xzAngle, rdA) mDxz = utils.getAbsMax(xzDeflection, rdD) print(sep) print(f"{pre}Report in XZ:") print(f"{mS:20} {mSxz:10} {self.ShearUnits.Label}") print(f"{mM:20} {mBxz:10} {self.MomentUnits.Label}") print(f"{mA:20} {mAxz:10} {self.AngleUnits.Label}") print(f"{mD:20} {mDxz:10} {self.DeflectionUnits.Label}") # done w console ouput print(sep) # Show plots of XY/XZ params & final beam deflection if showPlots: print(f"{pre}generating beam plots...") xyParams = (xyShear, xyBending, xyAngle, xyDeflection) xzParams = (xzShear, xzBending, xzAngle, xzDeflection) self.showPlots(xVals, xyParams, xzParams) print(f"done.") # if desired, output results to .csv file if outputToFile: # if the output folder doesnt exist, create it outputFolderName = "beam-analysis-results" if not os.path.exists(outputFolderName): os.makedirs(outputFolderName) # generate filename from beam params print(f"{pre}outputting to file in {outputFolderName}/...") filename = outputFolderName + "/" + f"beam-analysis-results-l{self.L}-cs{self.CrossSection.CrossSectionType.name}".replace('.', '_') + ".csv" # write the mS, mB, mA, MD vals for XY and XZ as well as some beam params with open(filename, 'w') as resultsFile: resultsFile.write("Beam Analysis Results\n") resultsFile.write("\n") resultsFile.write("Beam\n") resultsFile.write(f"length:, {self.L}\n") resultsFile.write(f"cross-section:, {self.CrossSection.CrossSectionType.name}\n") resultsFile.write(f"E:, {self.E}\n") resultsFile.write(f"I:, {self.I}\n") resultsFile.write("\n") # loads in XY if hasXY: resultsFile.write("Applied Loads in XY\n") resultsFile.write("Load Type, Start, Stop, Magnitude\n") for load in self.SingularityXY.AppliedLoads: if isinstance(load, DistributedLoad): resultsFile.write(f"{load.AppliedLoadType.name}, {load.Start}, {load.Stop}, {load.Magnitude}\n") else: resultsFile.write(f"{load.AppliedLoadType.name}, {load.Location}, N/A, {load.Magnitude}\n") resultsFile.write("\n") # loads in XZ if hasXZ: resultsFile.write("Applied Loads in XZ\n") resultsFile.write("Load Type, Start, Stop, Magnitude\n") for load in self.SingularityXZ.AppliedLoads: if isinstance(load, DistributedLoad): resultsFile.write(f"{load.AppliedLoadType.name}, {load.Start}, {load.Stop}, {load.Magnitude}\n") else: resultsFile.write(f"{load.AppliedLoadType.name}, {load.Location}, N/A, {load.Magnitude}\n") resultsFile.write("\n") # max vals in XY if hasXY: resultsFile.write("XY Plane\n") resultsFile.write(f"{mS} {self.ShearUnits}, {mSxy}\n") resultsFile.write(f"{mM} {self.MomentUnits}, {mBxy}\n") resultsFile.write(f"{mA} {self.AngleUnits}, {mAxy}\n") resultsFile.write(f"{mD} {self.DeflectionUnits}, {mDxy}\n") resultsFile.write("\n") # max vals in XZ if hasXZ: resultsFile.write("XZ Plane\n") resultsFile.write(f"{mS} {self.ShearUnits}, {mSxz}\n") resultsFile.write(f"{mM} {self.MomentUnits}, {mBxz}\n") resultsFile.write(f"{mA} {self.AngleUnits}, {mAxz}\n") resultsFile.write(f"{mD} {self.DeflectionUnits}, {mDxz}\n") resultsFile.write("\n") print(f"done.")