案例背景
这个例子的来源是sap2000的验证问题示例1-001,例子通过从头开始创建示例来验证软件计算的精确性问题:通过运行分析、提取结果并将软件计算结果与手算的值进行比较。例子比较简短,适合用来做相应的测试与后面的学习拓展。
步骤详解
打开软件
需要安装python的comtypes包,通过comtypes库提供的CreateObject创建Sap2000的实例,函数参数为所要创建的应用程序类名,先尝试打开已经运行的sap2000,如果没有,就再打开新的sap2000。以下的代码就是为了实现这个过程,这里是考虑到了各种可能的情况,实际使用的时候往往不需要这么复杂(比如直接开一个活动模型)。
# 导入需要的模块
# os模块负责程序与操作系统的交互,提供访问操作系统底层的接口
import os
# sys模块负责程序与python解释器的交互,提供一系列的函数和变量,用于操控python的运行时的环境(访问python编译器使用的变量及交互函数)
import sys
# comtypes包是纯python,轻量级的COM客户端和服务框架,基于ctypes的Python的FFI包,可以在python的环境中使用该包的各类模块
import comtypes.client
# 程序启动新的实例
AttachToInstance = False
# 是否指明程序的路径
SpecifyPath = False
# 程序路径
ProgramePath = "D:\Program Files\Computers and Structures\SAP2000 24\SAP2000.exe"
# 创建API文件的地址(所需要存储的目标地址,这个可以自定义)
APIPath = 'E:\SAP2000APItest\Example3'
# os.path模块主要用于文件的属性获取
# 如果系统中的'APIPath'这个文件夹的路径不存在,直接报一个"OSError"然后程序终止
if not os.path.exists(APIPath):
try:
os.makerdirs(APIPath)
except OSError:
pass
# os.sep表示分隔符/或者\,在后续需要添加子文件夹或者读取文件夹下的所有的文件,需要加上相应的分隔符
ModelPath = APIPath +os.sep +'test03.sdb'
helper = comtypes.client.CreateObject('SAP2000v1.Helper')
# QueryInterface:可以通过此函数来查询某个组件是否支持某个特定的接口
# 导入comtypes.client会自动创建comtypes.gen子包
# 若支持QueryInterface将返回一个指向些接口的指针,不支持返回值将是一个错误代码
helper = helper.QueryInterface(comtypes.gen.SAP2000v1.cHelper)
if AttachToInstance:
# 附加到正在运行的sap2000实例中来,需要获取相应的参数(活动模型)
try:
mySapObject = helper.Getobject('CSI.SAP2000.API.SapObject')
except (OSError,comtypes.COMError):
# 找不到正在运行的实例或未能附加
print('No running instance of the programe found or failed to attach.')
sys.exit(-1)
else:
# 此时需要启动新的sap2000,主要有一下的两种方式
# 1、使用函数helper.CreateObject(ProgramPath),根据程序文件路径建立SapObject实例
# 2、使用helper.CreatObjectProgID('CSI.SAP2000.API.SapObject')函数根据软件的program ID启动建立SapObject实例
if SpecifyPath:
try:
mySapObject = helper.CreatObject(ProgramePath)
except(OSError,comtypes.COMError):
print('Cannot start a new instance of the program from" + ProgramPath')
sys.exit(-1)
else:
try:
mySapObject = helper.CreateObjectProgID('CSI.SAP2000.API.SapObject')
except(OSError,comtypes.COMError):
print('Cannot start a new instance of the program')
sys.exit(-1)
# 最后通过mySapObject.ApplicationStart()函数启动sap2000
mySapObject.ApplicationStart()
创建一个新的空白模型
SapModel = mySapObject.SapModel
SapModel.InitializeNewModel()
ret = SapModel.File.NewBlank()
定义各项同性属性数据
#assign isotropic mechanical properties to material
# 将各项力学性能指定给材质,相关的4个参数分别为:材质名称、弹性模量、泊松比、热膨胀系数
ret = SapModel.PropMaterial.SetMPIsotropic('CONC',3600,0.2,5.5E-6)
SapModel = mySapObject.SapModel
SapModel.InitializeNewModel()
ret = SapModel.File.NewBlank()#assign isotropic mechanical properties to material
# 将各项力学性能指定给材质,相关的4个参数分别为:材质名称、弹性模量、泊松比、热膨胀系数
ret = SapModel.PropMaterial.SetMPIsotropic('CONC',3600,0.2,5.5E-6)

设置截面的属性修正
添加自定义材料使用SapModel.PropMaterial.SetMaterial函数,然后根据材料类型设置参数,使用set开头的函数进行材料参数的设置(例如使用SapModel.PropMaterial.SetMpIsotropic函数设置材料的弹性模量、泊松比、热膨胀系数,函数的具体使用需要查看相关的函数说明:最大的资料就是帮助文档,也是最原始最全面的文档)。

在截面定义这一块主要是截面定义、编辑、删除、参数设置等,每种类型的截面均有单独的定义函数,具体可以查看以set开头的函数(这里面的截面种类还是特别特别的多的,值得自己去注意)
代码层面
# 修改截面的属性
ModValue = [1000,0,0,1,1,1,1,1,1]
ret = SapModel.PropFrame.SetModifiers('R1',ModValue)
软件操作层面
# 修改截面的属性
ModValue = [1000,0,0,1,1,1,1,1,1]
ret = SapModel.PropFrame.SetModifiers('R1',ModValue)
通过坐标系来添加框架单元
然后就是构件的绘制:在帮助文件中查看Frame单元的相关函数,包括单元绘制、荷载指定以及相关参数的调整一种是通过坐标值建立杆件另一种通过节点编号建立杆件。
代码部分:这里主要通过坐标值来添加Frame单元,使用函数SapModel.FrameObj.AddByCoord通过坐标值添加杆件,FrameName1为ByRef变量,要得到在函数中改变后的值,需要将变量名放在等号的左侧得到改变后的值。在建模的过程中,可以随时根据需要调整模型的单位制,使用函数SapModel.SetPresentUnits()设置当前单位制,此后的代码输入的数据要与设置的单元相统一。
# 通过坐标系来添加框架单元
FrameName1,FrameName2,FrameName3 = '' , '' , ''
[FrameName1,ret] = SapModel.FrameObj.AddByCoord(0,0,0,0,0,10,FrameName1,'R1','1','Global')
[FrameName2,ret] = SapModel.FrameObj.AddByCoord(0,0,10,8,0,16,FrameName2,'R1','2','Global')
[FrameName3,ret] = SapModel.FrameObj.AddByCoord(-4,0,10,0,0,10,FrameName3,'R1','3','Global')

施加基础节点约束
使用SapModel.FrameObj.GetPoints函数得到杆件端部的节点编号,使用SapModel.PointObj.SetRestraint函数设定节点的约束条件
代码部分
# 施加节点约束
PointName1 , PointName2 = '', ''
# 指定节点约束为u1,u2,u3.r1,剩余的方向全部释放约束
Restraint = [True,True,True,True,False,False]
# 获取FrameName1的节点1和节点2,并将其中的节点1设置为定义好的约束形式
[PointName1,PointName2,ret] = SapModel.FrameObj.GetPoints(FrameName1,PointName1,PointName2)
ret = SapModel.PointObj.SetRestraint(PointName1,Restraint)
# 同样的方式对FrameName2的节点2施加节点约束
Restraint = [True,True,False,False,False,False]
[PointName1,PointName2,ret] = SapModel.FrameObj.GetPoints(FrameName2,PointName1,PointName2)
ret = SapModel.PointObj.SetRestraint(PointName2,Restraint)
设置7种荷载模式
-
使用函数SapModel.PointObj.SetLoadForce为节点指定集中荷载
-
使用函数SapModel.FrameObj.SetLoadDistributed函数指定杆件上的均布荷载
# 添加荷载模式
# 选定荷载模式为第八种的Other方式
LTYPE_OTHER = 8
# 设置名称为1~7的荷载模式
ret = SapModel.LoadPatterns.Add('1',LTYPE_OTHER,1,True)
ret = SapModel.LoadPatterns.Add('2',LTYPE_OTHER,0,True)
ret = SapModel.LoadPatterns.Add('3',LTYPE_OTHER,0,True)
ret = SapModel.LoadPatterns.Add('4',LTYPE_OTHER,0,True)
ret = SapModel.LoadPatterns.Add('5',LTYPE_OTHER,0,True)
ret = SapModel.LoadPatterns.Add('6',LTYPE_OTHER,0,True)
ret = SapModel.LoadPatterns.Add('7',LTYPE_OTHER,0,True)
施加荷载
# 添加荷载模式
# 选定荷载模式为第八种的Other方式
LTYPE_OTHER = 8
# 设置名称为1~7的荷载模式
ret = SapModel.LoadPatterns.Add('1',LTYPE_OTHER,1,True)
ret = SapModel.LoadPatterns.Add('2',LTYPE_OTHER,0,True)
ret = SapModel.LoadPatterns.Add('3',LTYPE_OTHER,0,True)
ret = SapModel.LoadPatterns.Add('4',LTYPE_OTHER,0,True)
ret = SapModel.LoadPatterns.Add('5',LTYPE_OTHER,0,True)
ret = SapModel.LoadPatterns.Add('6',LTYPE_OTHER,0,True)
ret = SapModel.LoadPatterns.Add('7',LTYPE_OTHER,0,True)
软件中的施加
# 施加节点约束
PointName1 , PointName2 = '', ''
# 指定节点约束为u1,u2,u3.r1,剩余的方向全部释放约束
Restraint = [True,True,True,True,False,False]
# 获取FrameName1的节点1和节点2,并将其中的节点1设置为定义好的约束形式
[PointName1,PointName2,ret] = SapModel.FrameObj.GetPoints(FrameName1,PointName1,PointName2)
ret = SapModel.PointObj.SetRestraint(PointName1,Restraint)
# 同样的方式对FrameName2的节点2施加节点约束
Restraint = [True,True,False,False,False,False]
[PointName1,PointName2,ret] = SapModel.FrameObj.GetPoints(FrameName2,PointName1,PointName2)
ret = SapModel.PointObj.SetRestraint(PointName2,Restraint)-
使用函数SapModel.PointObj.SetLoadForce为节点指定集中荷载
-
使用函数SapModel.FrameObj.SetLoadDistributed函数指定杆件上的均布荷载
# 添加荷载模式
# 选定荷载模式为第八种的Other方式
LTYPE_OTHER = 8
# 设置名称为1~7的荷载模式
ret = SapModel.LoadPatterns.Add('1',LTYPE_OTHER,1,True)
ret = SapModel.LoadPatterns.Add('2',LTYPE_OTHER,0,True)
ret = SapModel.LoadPatterns.Add('3',LTYPE_OTHER,0,True)
ret = SapModel.LoadPatterns.Add('4',LTYPE_OTHER,0,True)
ret = SapModel.LoadPatterns.Add('5',LTYPE_OTHER,0,True)
ret = SapModel.LoadPatterns.Add('6',LTYPE_OTHER,0,True)
ret = SapModel.LoadPatterns.Add('7',LTYPE_OTHER,0,True)
施加荷载
# 添加荷载模式
# 选定荷载模式为第八种的Other方式
LTYPE_OTHER = 8
# 设置名称为1~7的荷载模式
ret = SapModel.LoadPatterns.Add('1',LTYPE_OTHER,1,True)
ret = SapModel.LoadPatterns.Add('2',LTYPE_OTHER,0,True)
ret = SapModel.LoadPatterns.Add('3',LTYPE_OTHER,0,True)
ret = SapModel.LoadPatterns.Add('4',LTYPE_OTHER,0,True)
ret = SapModel.LoadPatterns.Add('5',LTYPE_OTHER,0,True)
ret = SapModel.LoadPatterns.Add('6',LTYPE_OTHER,0,True)
ret = SapModel.LoadPatterns.Add('7',LTYPE_OTHER,0,True)
软件中的施加
# 添加荷载模式
# 选定荷载模式为第八种的Other方式
LTYPE_OTHER = 8
# 设置名称为1~7的荷载模式
ret = SapModel.LoadPatterns.Add('1',LTYPE_OTHER,1,True)
ret = SapModel.LoadPatterns.Add('2',LTYPE_OTHER,0,True)
ret = SapModel.LoadPatterns.Add('3',LTYPE_OTHER,0,True)
ret = SapModel.LoadPatterns.Add('4',LTYPE_OTHER,0,True)
ret = SapModel.LoadPatterns.Add('5',LTYPE_OTHER,0,True)
ret = SapModel.LoadPatterns.Add('6',LTYPE_OTHER,0,True)
ret = SapModel.LoadPatterns.Add('7',LTYPE_OTHER,0,True)



对于荷载模式6:
-
在框架1左端的荷载为0.9987,右端的荷载为0.3744
-
在框架2左端的荷载为-0.3744,右端为0

对于荷载模式7:在框架2的跨中位置施加集中荷载

保存并创建分析模型
# 保存模型
set = SapModel.File.Save(ModelPath)
# 运行模型,在分析的过程中会创建一个分析模型
set = SapModel.Analyze.RunAnalysis()
初始化sap2000的计算结果
# 初始化sap2000的计算结果,结合后面的代码,这里主要是想输出不同荷载模式下的FrameName2的节点2的位移。
SapResult = [0,0,0,0,0,0,0]
[PointName1,PointName2,ret] = SapModel.FrameObj.GetPoints(FrameName2,PointName1,PointName2)
# 保存模型
set = SapModel.File.Save(ModelPath)
# 运行模型,在分析的过程中会创建一个分析模型
set = SapModel.Analyze.RunAnalysis()# 初始化sap2000的计算结果,结合后面的代码,这里主要是想输出不同荷载模式下的FrameName2的节点2的位移。
SapResult = [0,0,0,0,0,0,0]
[PointName1,PointName2,ret] = SapModel.FrameObj.GetPoints(FrameName2,PointName1,PointName2)
初始化荷载模式从1~7的sap2000的计算结果:这里采用的是for循环的方式保存建立的模型,并进行分析,在分析完成后提取工况下的位移结果,使用SapModel.Results.JointDispl函数得到节点位移结果,在输出位移结果前,清除设置的荷载工况,然后在设置要输出结果的荷载工况,再使用节点位移函数输出结果,保存建立的模型,并运行分析,分析完成后读取某一节点所有工况的位移。
对结果进行相应的打印
-
第一行是软件计算结果
-
第二行是手算结结果
-
第三行是误差百分比
第一行是软件计算结果
第二行是手算结结果
第三行是误差百分比
程序运行截图
-0.026389708333499594
-0.02639
-1.1052159924473948e-05
0.0629596111115078
0.06296
-6.1767549587310455e-06
0.0629596111115078
0.06296
-6.1767549587310455e-06
-0.2963018518537188
-0.2963
6.249928176993436e-06
0.3125018518538204
0.3125
5.92593222537019e-06
0.11555582518591315
0.11556
-3.612680933584578e-05
0.006511371527818799
0.00651
0.0002106801564976113
软件输出截图

附带一些语法的理解
SetRestrain
语法:SapModel.PointObj.SetRestraint
Add
语法:SapObject.SapModel.LoadPatterns.Add
主要的一些荷载模式
-
恒载
-
附加恒载
-
活载
-
...
-
地震
-
风荷载
-
雪荷载
-
其他荷载
-
移动荷载
-
温度荷载
-
屋面活荷载
-
....其他的种类特别的多....
SelfWTMultiplier(自乘系数)
AddLoadCase(添加荷载工况)
恒载
附加恒载
活载
...
地震
风荷载
雪荷载
其他荷载
移动荷载
温度荷载
屋面活荷载
....其他的种类特别的多....
AddLoadCase(添加荷载工况)
如果为True,则添加与新的荷载模式对应的线性静态荷载工况
SetLoadForce
语法:SetLoadPointSetLoadDistributed
SetModifiers
语法:SapObject.SapModel.FrameObject.SetModifiers
相关的一些参数:
Name:现有的框架或组的名称,具体取决于项目类型的值
值:8个无单位的修饰参数组成的一个数组
-
0:横截面修改
-
1:局部2轴的剪切面积
-
2:局部3轴的剪切面积
-
3:扭转常数的修改
-
4:局部2轴的惯性矩的修改
-
5:局部3轴的惯性矩的修改
-
6:质量修改
-
7:重量修改
项目对象:
-
0:对象
-
1:组
-
2:所选择的对象
DeselectAllCasesAndCombosForOutput
语法:
SapObject.SapModel.Results.Setup.DeselectAllCasesAndCombosForOutput
备注:
-
该功能取消悬着输出的所有荷载工况和和咋组合
-
如果成功取消选择case和combo,则函数返回0,否则返回非0
SetCaseSelectedForOutput
语法:SapObject.SapModel.Results.Setup.SetCaseSelectedForOutput
参数:
Name:现有的荷载工况的名称
Selected:如果要选择指定的荷载工况进行输出,此项就为True,否则就为False
备注:
-
函数用于设置为输出标志选择的荷载工况
-
如果成功设置所选标志,函数就返回0,否则就返回非0
Results.JointDispl
语法:SapObject.SapModel.Results.JointDispl
备注:
现有的点对象、点元素或点对象的名称,具体取决于
Item TypeElm itemItem TypeElm item中需要枚举的以下的项目
-
0:对象元素,结果请求针对与Name项指定的点对象对应的点元素
-
1:元素,结果请求针对Name项指定的point元素
-
2:组元素,结果请求针对Name项指定的组中直接或间接指定的所有点元素
-
3:选择元素,直接或间接选择的所有点元素的结果将被忽略,Name项将被忽略
NumbeResults(程序返回结果的总数)
对象:.......元素:包含与每个结果关联的点元素名称
荷载模式:包含与每个结果关联的分析的工况或荷载组合的名称
分析步类型:包含每个结果的步骤类型(如果有)
分析步数量:包含每个结果的步骤
备注:
函数用于反应指定关键点节点位移,这里展示出来的位移是相对位移
SetCaseSelecedForOutput
语法:SapObject.SapModel.Results.Setup.SetCaseSelectedForOutput
参数说明:
-
Name:存在的荷载模式
-
Selected:如果要选择指定的荷载工况进行输出,则输出为True,否者输出为False
备注:
-
这个函数用于设置输出标志选择的荷载工况
-
如果成功设置所选标志,则函数返回0,否则返回非0
后记
后续话还需要进行相应的输出,还是以例子的形式展示出来。
