diff --git a/openstaad/geometry.py b/openstaad/geometry.py index 938887e..bac9532 100644 --- a/openstaad/geometry.py +++ b/openstaad/geometry.py @@ -11,65 +11,65 @@ def __init__(self): self._geometry = self._staad.Geometry self._functions= [ - "AddBeam", - "AddNode", - "ClearMemberSelection", - "CreatePhysicalMember", - "DeletePhysicalMember", - "DoTranslationalRepeat", - "GetAnalyticalMemberCountForPhysicalMember", - "GetAnalyticalMembersForPhysicalMember", - "GetBeamLength", - "GetBeamList", - "GetBeamsConnectedAtNode", - "GetGroupCount", - "GetGroupEntities", - "GetGroupEntityCount", - "GetGroupNames", - "GetIntersectBeamsCount", - "GetLastBeamNo", - "GetLastNodeNo", - "GetLastPhysicalMemberNo", - "GetMemberCount", - "GetMemberIncidence", - "GetNodeCoordinates", - "GetNodeCount", - "GetNodeDistance", - "GetNodeIncidence", - "GetNodeList", - "GetNodeNumber", - "GetNoOfBeamsConnectedAtNode", - "GetNoOfSelectedBeams", - "GetNoOfSelectedNodes", - "GetNoOfSelectedPhysicalMembers", - "GetPMemberCount", - "GetPhysicalMemberCount", - "GetPhysicalMemberList", - "GetPhysicalMemberUniqueID", - "GetSelectedBeams", - "GetSelectedNodes", - "GetSelectedPhysicalMembers", - "IntersectBeams", - "SelectMultipleBeams", - "SelectMultiplePhysicalMembers", - "SelectPhysicalMember", - "SetPhysicalMemberUniqueID", - "GetLastPlateNo", - "GetNoOfSelectedPlates", - "GetPlateCount", - "GetPlateIncidence", - "GetPlateNodeCount", - "GetPlateList", - "GetPlateUniqueID", - "GetSelectedPlates", - "SelectPlate", - "SelectMultiplePlates", - "SetPlateUniqueID", - "ClearPlateSelection", - "AddPlate", - "AddMultiplePlates", - "DeletePlate", - "GetAreaOfPlates" + "AddBeam", + "AddMultiplePlates", + "AddNode", + "AddPlate", + "ClearMemberSelection", + "ClearPlateSelection", + "CreatePhysicalMember", + "DeletePhysicalMember", + "DeletePlate", + "DoTranslationalRepeat", + "GetAnalyticalMemberCountForPhysicalMember", + "GetAnalyticalMembersForPhysicalMember", + "GetAreaOfPlates", + "GetBeamLength", + "GetBeamList", + "GetBeamsConnectedAtNode", + "GetGroupCount", + "GetGroupEntities", + "GetGroupEntityCount", + "GetGroupNames", + "GetIntersectBeamsCount", + "GetLastBeamNo", + "GetLastNodeNo", + "GetLastPhysicalMemberNo", + "GetLastPlateNo", + "GetMemberCount", + "GetMemberIncidence", + "GetNodeCoordinates", + "GetNodeCount", + "GetNodeDistance", + "GetNodeIncidence", + "GetNodeList", + "GetNodeNumber", + "GetNoOfBeamsConnectedAtNode", + "GetNoOfSelectedBeams", + "GetNoOfSelectedNodes", + "GetNoOfSelectedPhysicalMembers", + "GetNoOfSelectedPlates", + "GetPMemberCount", + "GetPhysicalMemberCount", + "GetPhysicalMemberList", + "GetPhysicalMemberUniqueID", + "GetPlateCount", + "GetPlateIncidence", + "GetPlateList", + "GetPlateNodeCount", + "GetPlateUniqueID", + "GetSelectedBeams", + "GetSelectedNodes", + "GetSelectedPhysicalMembers", + "GetSelectedPlates", + "IntersectBeams", + "SelectMultipleBeams", + "SelectMultiplePhysicalMembers", + "SelectMultiplePlates", + "SelectPhysicalMember", + "SelectPlate", + "SetPhysicalMemberUniqueID", + "SetPlateUniqueID" ] for function_name in self._functions: diff --git a/openstaad/load.py b/openstaad/load.py index 622a45b..9041b0b 100644 --- a/openstaad/load.py +++ b/openstaad/load.py @@ -8,23 +8,30 @@ def __init__(self): self._load = self._staad.Load self._functions= [ - "AddMemberConcForce", - "AddResponseSpectrumLoadEx", - "AddSelfWeightInXYZ", - "AddWindDefinition", - "ClearPrimaryLoadCase", - "CreateNewPrimaryLoad", - "CreateNewReferenceLoad", - "DeleteDirectAnalysisDefinition", - "DeleteDirectAnalysisDefinitionParameter", - "DeleteWindDefinition", - "GetLoadCaseTitle", - "GetReferenceLoadCaseCount", - "SetLoadActive", - "SetReferenceLoadActive", - "AddNodalLoad", - "ClearReferenceLoadCase" - ] + "AddMemberConcForce", + "AddNodalLoad", + "AddResponseSpectrumLoadEx", + "AddSelfWeightInXYZ", + "AddWindDefinition", + "ClearPrimaryLoadCase", + "ClearReferenceLoadCase", + "CreateNewPrimaryLoad", + "CreateNewReferenceLoad", + "DeleteDirectAnalysisDefinition", + "DeleteDirectAnalysisDefinitionParameter", + "DeletePrimaryLoadCases", + "DeleteWindDefinition", + "GetLoadCombinationCaseCount", + "GetLoadCombinationCaseNumbers", + "GetLoadCaseTitle", + "GetLoadListCount", + "GetLoadType", + "GetPrimaryLoadCaseCount", + "GetReferenceLoadCaseCount", + "GetReferenceLoadCaseNumbers", + "SetLoadActive", + "SetReferenceLoadActive" + ] for function_name in self._functions: self._load._FlagAsMethod(function_name) @@ -42,6 +49,15 @@ def make_safe_array_long(array): return self._load.AddMemberConcForce(varBeamNo,varDirection,varForce,varD1,varD2) + def AddNodalLoad(self, nodes : list[int], fx : float, fy:float, fz:float, mx:float, my:float, mz:float): + def make_safe_array_long(array): + return automation._midlSAFEARRAY(ctypes.c_long).create(array) + + safe_list = make_safe_array_long(nodes) + varNodeNo = make_variant_vt_ref(safe_list, automation.VT_ARRAY | automation.VT_I4) + + self._load.AddNodalLoad(varNodeNo,fx, fy, fz, mx, my, mz) + def AddResponseSpectrumLoadEx(self, code_number:int, modal_combination:int, set_names_1:list, set_values_1:list, spectrum_data_pairs:list[tuple],set_names_2:list=None, set_values_2:list=None): """Adds Response Spectrum load item to the currently active load case. @@ -102,6 +118,9 @@ def ClearPrimaryLoadCase(self,load_case:int,is_reference_lc:bool=False): """ return self._load.ClearPrimaryLoadCase(load_case,is_reference_lc) + def ClearReferenceLoadCase(self,reference_load_number: int): + self._load.ClearReferenceLoadCase(reference_load_number) + def CreateNewPrimaryLoad(self,LoadTitle:str="LOAD CASE X"): """ Creates new PRIMARY load case. @@ -128,6 +147,9 @@ def DeleteDirectAnalysisDefinitionParameter(self,parameter_type:int=0): """ return self._load.DeleteDirectAnalysisDefinitionParameter(parameter_type) + def DeletePrimaryLoadCases(self,load_case:int,is_reference:bool=False): + return self._load.DeletePrimaryLoadCases(load_case,is_reference) + def DeleteWindDefinition(self,type_No:int=0): """ Deletes Wind definition. All definitions will be deleted if this input is set as 0. @@ -140,6 +162,42 @@ def GetLoadCaseTitle(self,lc:int=0): """ return self._load.GetLoadCaseTitle(lc) + def GetLoadCombinationCaseCount(self): + """ + Gets total number of combination load case(s) present in the current structure. + """ + return self._load.GetLoadCombinationCaseCount() + + def GetLoadCombinationCaseNumbers(self): + """ + Gets all load combination case number(s). + """ + lc_case_count=self._load.GetLoadCombinationCaseCount() + safe_list = make_safe_array_long(lc_case_count) + lista = make_variant_vt_ref(safe_list, automation.VT_ARRAY | automation.VT_I4) + + self._load.GetLoadCombinationCaseNumbers(lista) + + return (lista[0]) + + def GetLoadListCount(self): + """ + Gets the number of existing load list(s) + """ + return self._load.GetLoadListCount() + + def GetLoadType(self,load_No:int): + """ + Returns primary load case category(s) as an long value. + """ + return self._load.GetLoadType(load_No) + + def GetPrimaryLoadCaseCount(self): + """ + Returns the total number of primary load cases present in the current structure. + """ + return self._load.GetPrimaryLoadCaseCount() + def GetReferenceLoadCaseCount(self): """ Returns the number of reference load case defined in Reference Load Definitions. @@ -158,17 +216,7 @@ def SetReferenceLoadActive(self,load_case:int): """ return self._load.SetReferenceLoadActive(load_case) - def AddNodalLoad(self, nodes : list[int], fx : float, fy:float, fz:float, mx:float, my:float, mz:float): - def make_safe_array_long(array): - return automation._midlSAFEARRAY(ctypes.c_long).create(array) - - safe_list = make_safe_array_long(nodes) - varNodeNo = make_variant_vt_ref(safe_list, automation.VT_ARRAY | automation.VT_I4) - - self._load.AddNodalLoad(varNodeNo,fx, fy, fz, mx, my, mz) - - def ClearReferenceLoadCase(self,reference_load_number: int): - self._load.ClearReferenceLoadCase(reference_load_number) + diff --git a/openstaad/output.py b/openstaad/output.py index 25aa489..82324c3 100644 --- a/openstaad/output.py +++ b/openstaad/output.py @@ -9,8 +9,12 @@ def __init__(self): self._functions= [ 'GetMemberEndForces', + 'GetMinMaxAxialForce', + 'GetMinMaxBendingMoment', + 'GetMinMaxShearForce', 'GetModalMassParticipationFactors', 'GetModeFrequency', + 'GetNoOfModesExtracted', 'GetSupportReactions' ] @@ -33,6 +37,57 @@ def GetMemberEndForces(self,beam, start = True, lc :int= 1,local: int = 0): return x.value[0] + def GetMinMaxAxialForce(self, beam:int, lc: int = 1): + """ + Returns maximum and minimum bending moments and their locations for specified member number, load case, and bending direction. + """ + ddmin = ctypes.c_double() + minpos = ctypes.c_double() + ddmax = ctypes.c_double() + maxpos = ctypes.c_double() + + retval = self._output.GetMinMaxAxialForce( + beam, lc, + ctypes.byref(ddmin), ctypes.byref(minpos), + ctypes.byref(ddmax), ctypes.byref(maxpos) + ) + + return ddmin.value, minpos.value, ddmax.value, maxpos.value + + def GetMinMaxBendingMoment(self, beam:int, direction: str, lc: int = 1): + """ + Returns maximum and minimum bending moments and their locations for specified member number, load case, and bending direction. + """ + ddmin = ctypes.c_double() + minpos = ctypes.c_double() + ddmax = ctypes.c_double() + maxpos = ctypes.c_double() + + retval = self._output.GetMinMaxBendingMoment( + beam, direction, lc, + ctypes.byref(ddmin), ctypes.byref(minpos), + ctypes.byref(ddmax), ctypes.byref(maxpos) + ) + + return ddmin.value, minpos.value, ddmax.value, maxpos.value + + def GetMinMaxShearForce(self, beam:int, direction: str, lc: int = 1): + """ + Returns maximum and minimum shear force and their locations for specified member number, load case, and force direction. + """ + ddmin = ctypes.c_double() + minpos = ctypes.c_double() + ddmax = ctypes.c_double() + maxpos = ctypes.c_double() + + retval = self._output.GetMinMaxShearForce( + beam, direction, lc, + ctypes.byref(ddmin), ctypes.byref(minpos), + ctypes.byref(ddmax), ctypes.byref(maxpos) + ) + + return ddmin.value, minpos.value, ddmax.value, maxpos.value + def GetModalMassParticipationFactors(self, var_mode: int): """ Get the modal mass participation factors in X, Y and Z directions for a given mode. @@ -45,6 +100,9 @@ def GetModalMassParticipationFactors(self, var_mode: int): return (round(patX.value,5), round(patY.value,5), round(patZ.value,5)) + def GetNoOfModesExtracted(self): + return self._output.GetNoOfModesExtracted() + def GetModeFrequency(self, var_mode:int): """ Get the natural frequency (Hz) for a given mode. diff --git a/openstaad/root.py b/openstaad/root.py index 2310c25..1dabb04 100644 --- a/openstaad/root.py +++ b/openstaad/root.py @@ -10,6 +10,7 @@ def __init__(self): self._functions = [ 'Analyze', + 'AnalizeEx', 'GetAnalysisStatus', 'GetApplicationVersion', 'GetBaseUnit', @@ -29,6 +30,12 @@ def __init__(self): def Analyze(self): self._root.Analyze() + def AnalyzeEx(self,silent:int,hidden:int,wait:int): + """ + This extended method analyzes the currently opened .STD file. This method is equivalent to running analysis from user interface. However, it has additional three arguments to specify whether to run the analysis in silent or hidden mode. The third parameter specifies whether the method should wait for the analysis to finish or return immediately. This method may be used in conjunction with SetSilentMode(), if one wants to suppress all dialog boxes displayed from the application during running of analysis. + """ + self._root.AnalyzeEx(silent,hidden,wait) + def GetAnalysisStatus(self): """ Get analysis status for the open STAAD Model.