
1.1 简单插件实例——创建带孔板有限元模型
熟悉Abaqus/CAE的人应该知道,当点击Plug-ins→Toolboxes→Examples菜单时,会弹出如图1.1所示工具条。
点击第一个按钮,弹出如图1.2所示窗口。

图1.1 插件程序工具条

图1.2 带孔板插件界面
这是Abaqus/CAE内嵌的一个简单插件程序(plug-in),在上述窗口中输入零件名、零件宽度、高度以及圆孔半径之后,点击“OK”,则会自动在Abaqus中生成带孔板的几何模型。
该程序仅能实现带孔板的几何创建,本节将以此为基础,在源程序的基础上稍加改进,使其可实现带孔板有限元分析模型的参数化建模。图1.3为改写之后的插件程序界面示意图。下面将对该插件程序的构成进行详细介绍。

图1.3 修改后的插件示意图
该插件程序共由4个文件组成。
(1)注册文件createPlateWithhole_plugin.py
(2)图形界面文件createPlateWithholeDB.py
(3)内核执行文件createPlateModul.py
(4)图标文件planewithhole.png
其中图标文件如图1.4所示,图标文件即为插件窗口中的示意图,Abaqus支持bmp、 gif、 png、 xpm等多种格式的图片,本实例中采用的是png格式图片,其他3个组成文件将在后面分别介绍。

图1.4 修改后的插件示意图
上述文件均存放在随书配套资源\chapter 1\createPlateWithhole文件夹内。将文件夹createPlateWithhole及内部文件复制到Abaqus工作目录或者安装目录下的Abaqus_plugins文件夹下(没有的话请自行创建该文件夹),例如:
安装目录D:\SIMULIA\6.10\Abaqus_plugins\createPlateWithhole
当前工作目录D:\TEMP\Abaqus_plugins
重新启动Abaqus/CAE主界面,在Plug-ins菜单下会出现名为“创建带孔板”的功能子菜单,如图1.5所示。

图1.5 插件菜单
将图1.3中所示的参数填写完整并执行程序,可自动生成带孔板拉伸的有限元模型,并可直接将其提交计算,模型如图1.6所示。

图1.6 由插件生成的带孔板模型示意图
提交计算后,可以得到图1.7所示的应力云图。

图1.7 带孔板应力云图
1.1.1 注册文件
本插件程序中的注册文件命名为createPlateWithhole_plugin.py,其主要作用是注册插件程序以及其中的关键字等。其程序源代码如下。
#文件名createPlateWithhole_plugin.py #中文编码
# -* - coding:UTF-8-*- from abaqusGui import* from abaqusConstants import ALL import osutils, os #################################################################### # Class definition #################################################################### class createPlateWithhole_plugin(AFXForm): #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ def__init__(self, owner): # Construct the base class. # AFXForm.__init__(self, owner) self.radioButtonGroups={} self.cmd=AFXGuiCommand(mode=self, method='createPlateFunction', objectName='createPlateModul', registerQuery=False) pickedDefault='' self.partnameKw=AFXStringKeyword(self.cmd, 'partname', True, 'part-1') self.widthKw=AFXFloatKeyword(self.cmd, 'width', True,100) self.heightKw=AFXFloatKeyword(self.cmd, 'height', True,100) self.radiusKw=AFXFloatKeyword(self.cmd, 'radius', True,5) #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ def getFirstDialog(self): import createPlateWithholeDB return createPlateWithholeDB.createPlateWithholeDB(self) #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ def doCustomChecks(self): # Try to set the appropriate radio button on. If the user did # not specify any buttons to be on, do nothing. # for kw1, kw2, d in self.radioButtonGroups.values(): try: value=d[kw1.getValue()] kw2.setValue(value) except: pass #对输入数据格式进行检查,不满足要求时提示警告 if self.widthKw.getValue()<=0: showAFXErrorDialog(getAFXApp().getAFXMainWindow(), '宽度必须为正数’) return False elif self.heightKw.getValue()<=0: showAFXErrorDialog(getAFXApp().getAFXMainWindow(), '高度必须为正数’) return False elif self.radiusKw.getValue()<=0: showAFXErrorDialog(getAFXApp().getAFXMainWindow(), '孔半径必须是正数.') return False else: return True #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ def okToCancel(self): # No need to close the dialog when a file operation (such # as New or Open) or model change is executed. # return False #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ # Register the plug-in # thisPath=os.path.abspath(__file__) #指定路径 thisDir=os.path.dirname(thisPath) toolset=getAFXApp().getAFXMainWindow().getPluginToolset() toolset.registerGuiMenuButton( buttonText=’创建带孔板’, object=createPlateWithhole_plugin(toolset), messageId=AFXMode.ID_ACTIVATE, icon=None, #指定图标为空 kernelInitString='import createPlateModul', #内核初始化指令 applicableModules=ALL, #指定使用模块,默认为全部 version='1.0', #软件版本 author='jly', #软件作者 description='N/A', #软件描述 helpUrl='N/A' #帮助文档路径指定 )
提示
以上代码是本书中出现的第一段代码,需要提醒读者注意的是,在Python语言中,代码的缩进是一种语法,Python依靠每行代码的缩进位置来判断代码的分块、区分代码块之间的层次关系,错误的缩进位置将会导致程序执行错误,读者应对此予以特别注意,有关Python编码规则的内容请参照本书2.3节内容。
编写代码时建议使用UltraEdit或者Notepad++等文本编辑软件,本书在编写过程中采用的是Notepad++软件(免费),该软件支持Python等多种语言的语法着色。
1.1.2 图形界面文件
图形界面文件的主要作用是定义各类窗体、控件,关联控件的执行命令及对象。通过定义文本框、单复选按钮、表格等各类控件,用户可以方便地将所需参数集成到统一的图形界面下,形成友好的输入输出界面。本插件程序中的图形界面文件命名为createPlateWithholeDB.py,其程序源代码如下。
# -* - coding:UTF-8-*- from abaqusConstants import* from abaqusGui import* from kernelAccess import mdb, session import os thisPath=os.path.abspath(__file__) #设置当前路径 thisDir=os.path.dirname(thisPath) ######################################################################### # Class definition ######################################################################### class createPlateWithholeDB(AFXDataDialog): #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ def__init__(self, form): # Construct the base class. # AFXDataDialog.__init__(self, form, ’带孔板参数化建模程序’, self.OK|self.CANCEL, DIALOG_ACTIONS_SEPARATOR) #创建对话框,该对话框有OK、CANCEL按键 okBtn=self.getActionButton(self.ID_CLICKED_OK) okBtn.setText('OK') #定义OK按钮 GroupBox_1=FXGroupBox(p=self, text=’参数’, opts=FRAME_GROOVE) AFXTextField(p=GroupBox_1, ncols=12, labelText=’零件名:', tgt=form.partnameKw, sel=0) #定义文本框 AFXTextField(p=GroupBox_1, ncols=12, labelText=’宽度(w):', tgt=form.widthKw, sel=0) AFXTextField(p=GroupBox_1, ncols=12, labelText=’高度(h):', tgt=form.heightKw, sel=0) AFXTextField(p=GroupBox_1, ncols=12, labelText=’半径(r):', tgt=form.radiusKw, sel=0) GroupBox_3=FXGroupBox(p=self, text=’示意图’, opts=FRAME_GROOVE) fileName=os.path.join(thisDir, r'planewithhole.png') #指定示意图图标 icon=afxCreatePNGIcon(fileName) #创建图标 FXLabel(p=GroupBox_3, text='', ic=icon) #定义示意图标签
1.1.3 内核执行文件
内核执行文件是插件程序的核心,其作用是驱动Abaqus/CAE执行内部命令,完成CAE建模以及数据处理等功能。本插件程序中的内核执行文件命名为createPlateModul.py,其程序源代码如下。
# -* - coding:UTF-8-*- from abaqus import* from abaqusConstants import* def createPlateFunction(partname, width, height, radius): #参数调用 mdb.models['Model-1'].ConstrainedSketch(name='__profile__' , sheetSize=200.0) mdb.models['Model-1'].sketches['__profile__'].rectangle(point1=(0.0,0.0), point2=(width, height)) mdb.models['Model-1'].sketches['__profile__'].CircleByCenterPerimeter(center=( width/2, height/2), point1=(width/2+radius, height/2)) mdb.models['Model-1'].Part(dimensionality=THREE_D, name=partname, type= DEFORMABLE_BODY) mdb.models['Model-1'].parts[partname].BaseShell(sketch= mdb.models['Model-1'].sketches['__profile__']) p=mdb.models['Model-1'].parts[partname] session.viewports['Viewport:1'].setValues(displayedObject=p) del mdb.models['Model-1'].sketches['__profile__'] #创建几何 mdb.models['Model-1'].Material(name='AL') mdb.models['Model-1'].materials['AL'].Elastic(table=((70000.0,0.3), )) mdb.models['Model-1'].HomogeneousShellSection(name='al', preIntegrate=OFF, material='AL', thicknessType=UNIFORM, thickness=1.0, thicknessField='', idealization=NO_IDEALIZATION, poissonDefinition=DEFAULT, thicknessModulus=None, temperature=GRADIENT, useDensity=OFF, integrationRule=SIMPSON, numIntPts=5) f=p.faces faces=f.getSequenceFromMask(mask=('[#1]', ), ) region=p.Set(faces=faces, name='Set-2') p.SectionAssignment(region=region, sectionName='al', offset=0.0, offsetType=MIDDLE_SURFACE, offsetField='', thicknessAssignment=FROM_SECTION) #建立材料并赋予属性 session.viewports['Viewport:1'].partDisplay.setValues(mesh=ON) session.viewports['Viewport:1'].partDisplay.meshOptions.setValues( meshTechnique=ON) session.viewports['Viewport:1'].partDisplay.geometryOptions.setValues( referenceRepresentation=OFF) #切换到mesh模块 p=mdb.models['Model-1'].parts[partname] p.seedPart(size=4.0, deviationFactor=0.1, minSizeFactor=0.1) f=p.faces pickedRegions=f.findAt(((width/2,0.0,0.0), )) p.setMeshControls(regions=pickedRegions, elemShape=QUAD, algorithm=MEDIAL_AXIS) #设定网格划分格式 p.generateMesh() #网格划分 a=mdb.models['Model-1'].rootAssembly session.viewports['Viewport:1'].setValues(displayedObject=a) #切换到装配模块 a=mdb.models['Model-1'].rootAssembly a.DatumCsysByDefault(CARTESIAN) p=mdb.models['Model-1'].parts[partname] a.Instance(name=partname+'-1', part=p, dependent=ON) #创建装配实例 mdb.models['Model-1'].StaticStep(name='Step-1', previous='Initial', nlgeom=ON) session.viewports['Viewport:1'].assemblyDisplay.setValues(step='Step-1') #创建分析步 session.viewports['Viewport:1'].view.setValues(nearPlane=335.564, farPlane=385.546, width=212.48, height=142.547, viewOffsetX=13.3712, viewOffsetY=-7.13345) a=mdb.models['Model-1'].rootAssembly e1=a.instances[partname+'-1'].edges edges1=e1.findAt(((0.0, height/2,0.0), )) region=a.Set(edges=edges1, name='Set-1') mdb.models['Model-1'].DisplacementBC(name='BC-1', createStepName='Step-1', region=region, u1=0.0, u2=0.0, u3=0.0, ur1=0.0, ur2=0.0, ur3=0.0, amplitude=UNSET, fixed=OFF, distributionType=UNIFORM, fieldName='', localCsys=None) #施加边界条件 edges1=e1.findAt(((width, height/2,0.0), )) region=a.Set(edges=edges1, name='Set-2') mdb.models['Model-1'].DisplacementBC(name='BC-2', createStepName='Step-1', region=region, u1=2.0, u2=UNSET, u3=UNSET, ur1=UNSET, ur2=UNSET, ur3=UNSET, amplitude=UNSET, fixed=OFF, distributionType=UNIFORM, fieldName='', localCsys=None) #施加位移载荷 mdb.Job(name='Job-hole', model='Model-1', description='', type=ANALYSIS, atTime=None, waitMinutes=0, waitHours=0, queue=None, memory=50, memoryUnits=PERCENTAGE, getMemoryFromAnalysis=True, explicitPrecision=SINGLE, nodalOutputPrecision=SINGLE, echoPrint=OFF, modelPrint=OFF, contactPrint=OFF, historyPrint=OFF, userSubroutine='', scratch='', multiprocessingMode=DEFAULT, numCpus=1) #创建job