最近在学 HYPERMESH二次开发,发觉可以用它做很多有用的东西以简化工作。下面例子讲述的是如何利用 hypermesh二次开发
在ansys模板下求2d单元面积。
问题描述:在Ansys模板下,如果要用下面工具求2d单元面积,则单元必须要有单元类型,如果没有单元类型,则面积不可求,
这就有一个麻烦,当我们须要导出ansys的只是三维模型,那么二维单元相对于后面计算来说是不须导出的,所以也不须赋与其单
类型,但可能计算时又要用到模型某个面的面积,这样又必须赋与其单元 ,通常做法是为单元赋与shell 93单元类型,那么有没有
一种更直接的方法测量任何2d单元的面积,不管它有没有单元类型呢?这就是本二次开发的一个目的。
首先,要创要创建一个名称空间,名字 InquireArea,如下
namespace eval ::Ansys::ToolKit::InquireArea {
set elem_ids_list []
set area_sum 0
}
该名称空间创建了两个变量,其中elem_ids_list 用存放选取的单元ID值,area_sum用来存放最后总的面积,并且作为结果输出。
下一步,创建一个计算单元面积的过程:
proc ::Ansys::ToolKit::InquireArea::CalculateArea { args } {
#声名变量为该名称空间的变量
variable elem_ids_list
variable area_sum 0
#计算每一个单元的面积并累加到area_sum中去
foreach elem_id $elem_ids_list {
#通过dataname访问每个单元的面积
set current_elem_area [ hm_getentityvalue elems $elem_id "area" 0 ]
set area_sum [ expr $current_elem_area + $area_sum ]
}
#这句语句是算完面积清空单元列表,以便下一次求面积
set ::Ansys::ToolKit::InquireArea::elem_ids_list []
}
有了计算单元的过程,下一步我们要做什么呢?当然我们要做是把要求面积的单选取出来,下面这个过程就是选取单元的过程
proc ::Ansys::ToolKit::InquireArea::AddElems { args } {
if { [lindex $args 0] == "typechangenotify"} {
return;
}
switch [lindex $args 0] {
"getadvselmethods" {
*entityhighlighting 1
*clearmark elems 1
wm withdraw .inquireAreaWindow;
*createmarkpanel elems 1 "Select elements:"
wm deiconify .inquireAreaWindow;
eval lappend ::Ansys::ToolKit::InquireArea::elem_ids_list [ hm_getmark elems 1 ]
*clearmark elems 1
*entityhighlighting 0
if { [ llength $::Ansys::ToolKit::InquireArea::elem_ids_list ] == 0 } {
tk_messageBox -message "No elements were selected. \n Please select elements to inquire area" -title "Altair HyperMesh"
return;
}
return;
}
"reset" {
set ::Ansys::ToolKit::InquireArea::elem_ids_list []
return;
}
default {
return 1;
}
}
}
这个过程看起来有点复杂,其实是比较简单的,下面拆解分析下它,
首先,这个proc中部分语句是为gui服务的,GUI编写放在后面,你也可以联合起来看,现在我们只看单元选取的,
很简单,就一句语句 *createmarkpanel elems 1 "Select elements:" ,找到了没呢?
有了这条语句,当TCL运行到它时,就会弹出选择面板了
在它下面的一条语句是 eval lappend ::Ansys::ToolKit::InquireArea::elem_ids_list [ hm_getmark elems 1 ] ,这条语
句的作用取得刚选取的单元ID值并把它们附到elem_ids_list 中去,到这一步为止,elem_ids_list 列表已经有东西了,
也就是,我们已经把单元选出来了,此时只调用proc ::Ansys::ToolKit::InquireArea::CalculateArea 过程,就可以算出
面积来了。
那么下步做什么呢,那当然是要把我们的结果显示出来,有很多种方法,其中最简单的是调用TCL语言TK语句:
tk_messageBox -message " Area is : $::Ansys::ToolKit::InquireArea::area_sum" -title "Inquire Area " -icon info
这个东西有个坏处,就是你不能复制里面的面积信息,也就是说,你只能看。
那么我们可以做一简单的GUI,通过entry(输入框)来取得面积信息
上面那个选取单元的过程提到过,那里部分语句是为GUI 服务,下面写这个GUI
首先,这个GUI用到hypermesh hwt toolkit,因此第上步加入下面语句
package require hwt;
这样我们就可以大胆用hwt里面的一些控件了
此外还用到hypermesh软件包自带的一过程,我们也要把它SOURCE进来
SourceFile [file join [hm_info -appinfo SPECIFIEDPATH hw_tcl_common] "hw" "collector" "hwcollector.tcl"]
好了,下面可能是读者最心的,如何创建一个窗口,通常还是把它放在一个过程里面
proc ::Ansys::ToolKit::InquireArea::InquireAreaWindow { args } {
::Ansys::ToolKit::InquireArea::Desroy
hwt::CreateWindow .inquireAreaWindow \
-windowtitle "Inquire Area " \
-noGeometrySaving \
-cancelButton Cancel \
-helpButton help \
destroyOnUnpost \
-post;
#设置窗口最大与最小值
wm minsize .inquireAreaWindow 400 140;
wm maxsize .inquireAreaWindow 400 140;
#如果置顶窗口,加上它吧
wm attribute .inquireAreaWindow -topmost true
#取得空腔,也就窗口里面放控件的地方吧,这是个path
set base [ hwt::WindowRecess .inquireAreaWindow ]
#创建一个框架,然后我们才能往里放东西
set fra1 [ frame $base.fra1 ]
#创建了框架,还要把它显示出来吧,下面这语句就是把它显示出来
pack $fra1 -side top -anchor nw -fill x -expand false
#一个框架是不够的,多创建一个吧,反正不用钱的
set fra2 [ frame $base.fra2 ]
pack $fra2 -side top -anchor nw -fill x -expand false
#创建一个标签,
set elem_label [ label $fra1.elem_label \
-text "Select elements :" \
-font [hwt::AppFont] \
-justify center ]
#显示这个标签 ,至于里面的选项,不懂可以看TCL的参考书
pack $elem_label -side left -anchor nw -fill none -expand 0 -padx 4 -ipady 3
#创建选取单元按钮
set elems_button [Collector $fra1.addelems entity 1 HmMarkCol \
-types "elements" \
-withtype 0 \
-withReset 1 \
-callback "::Ansys::ToolKit::InquireArea::AddElems"]
#显示它
pack $fra1.addelems -side left -padx 3 -pady 5
#这里创建一个输入框,你可以从这里复制面积
set area_entry [ AddEntry $fra2.areaentry \
-label "Area = " \
-labelWidth 15 \
-entryWidth 24 \
-validate real \
-state normal \
-textVariable ::Ansys::ToolKit::InquireArea::area_sum ]
pack $area_entry -side left -anchor nw -padx 4 -pady 5
#这里计算面积的按钮,-command 调用了我们之前创建的过::Ansys::ToolKit::InquireArea::CalculateArea
#这样我们按下它时,就执行这个过程了
set get_area_but [ button $fra2.getareabut \
-text "Calculate" \
-command ::Ansys::ToolKit::InquireArea::CalculateArea]
pack $get_area_but -side left -anchor nw -padx 10 -pady 5 -ipadx 10 -ipady 3
}
相对是一个比较长的过程,先看一下效果,如果你是第一次接触GUI,估计不看效果也很头痛的
很简,两个entry ,两个按钮
好吧,下面我们分析一下吧
::Ansys::ToolKit::InquireArea::Desroy 调用一个Desroy 的过程,现在还没有写这个过程,接下来就写它吧
proc ::Ansys::ToolKit::InquireArea::Desroy { } {
destroy .inquireAreaWindow
}
就一条语句,其中.inquireAreaWindow叫做窗口路径,通过destroy语句,我们把窗口毁了,这样每次我们创建一
新的窗口之前,都会先毁一下窗口,保证只有一.inquireAreaWindow显示出来
通过这条语句,我们就可以创建下个窗口了
hwt::CreateWindow .inquireAreaWindow \
-windowtitle "Inquire Area " \
-noGeometrySaving \
-cancelButton Cancel \
-helpButton help \
destroyOnUnpost \
-post;
有兴趣的可以把这段语句与 package require hwt 一起放到复制到txt文档,保存为tcl运行一下吧
其中的选项我就不说,已经很很啰嗦啦,可以查看帮助,其它的请看注释
最后,加上这条语句:
::Ansys::ToolKit::InquireArea::InquireAreaWindow
各个过程就串接起来了
到现在为止,整个开发就完成了,,当然还有许多细节说不到的,请大家原谅
下面给出完整脚本:
namespace eval ::Ansys::ToolKit::InquireArea {
set elem_ids_list []
set area_sum 0
}
package require hwt;
SourceFile [file join [hm_info -appinfo SPECIFIEDPATH hw_tcl_common] "hw" "collector" "hwcollector.tcl"]
proc ::Ansys::ToolKit::InquireArea::CalculateArea { args } {
variable elem_ids_list
variable area_sum 0
foreach elem_id $elem_ids_list {
set current_elem_area [ hm_getentityvalue elems $elem_id "area" 0 ]
set area_sum [ expr $current_elem_area + $area_sum ]
}
set ::Ansys::ToolKit::InquireArea::elem_ids_list []
}
proc ::Ansys::ToolKit::InquireArea::Desroy { } {
destroy .inquireAreaWindow
}
proc ::Ansys::ToolKit::InquireArea::InquireAreaWindow { args } {
package require hwt
::Ansys::ToolKit::InquireArea::Desroy
hwt::CreateWindow .inquireAreaWindow \
-windowtitle "Inquire Area " \
-noGeometrySaving \
-cancelButton Cancel \
-helpButton help \
destroyOnUnpost \
-post;
wm minsize .inquireAreaWindow 400 140;
wm maxsize .inquireAreaWindow 400 140;
wm attribute .inquireAreaWindow -topmost true
set base [ hwt::WindowRecess .inquireAreaWindow ]
set fra1 [ frame $base.fra1 ]
pack $fra1 -side top -anchor nw -fill x -expand false
set fra2 [ frame $base.fra2 ]
pack $fra2 -side top -anchor nw -fill x -expand false
set elem_label [ label $fra1.elem_label \
-text "Select elements :" \
-font [hwt::AppFont] \
-justify center ]
pack $elem_label -side left -anchor nw -fill none -expand 0 -padx 4 -ipady 3
set elems_button [Collector $fra1.addelems entity 1 HmMarkCol \
-types "elements" \
-withtype 0 \
-withReset 1 \
-callback "::Ansys::ToolKit::InquireArea::AddElems"]
pack $fra1.addelems -side left -padx 3 -pady 5
set area_entry [ AddEntry $fra2.areaentry \
-label "Area = " \
-labelWidth 15 \
-entryWidth 24 \
-validate real \
-state normal \
-textVariable ::Ansys::ToolKit::InquireArea::area_sum ]
pack $area_entry -side left -anchor nw -padx 4 -pady 5
set get_area_but [ button $fra2.getareabut \
-text "Calculate" \
-command ::Ansys::ToolKit::InquireArea::CalculateArea]
pack $get_area_but -side left -anchor nw -padx 10 -pady 5 -ipadx 10 -ipady 3
}
proc ::Ansys::ToolKit::InquireArea::AddElems { args } {
if { [lindex $args 0] == "typechangenotify"} {
return;
}
switch [lindex $args 0] {
"getadvselmethods" {
*entityhighlighting 1
*clearmark elems 1
wm withdraw .inquireAreaWindow;
*createmarkpanel elems 1 "Select elements:"
wm deiconify .inquireAreaWindow;
eval lappend ::Ansys::ToolKit::InquireArea::elem_ids_list [ hm_getmark elems 1 ]
*clearmark elems 1
*entityhighlighting 0
if { [ llength $::Ansys::ToolKit::InquireArea::elem_ids_list ] == 0 } {
tk_messageBox -message "No elements were selected. \n Please select elements to inquire area" -title "Altair HyperMesh"
return;
}
return;
}
"reset" {
set ::Ansys::ToolKit::InquireArea::elem_ids_list []
return;
}
default {
return 1;
}
}
}
::Ansys::ToolKit::InquireArea::InquireAreaWindow
下面是运行过程:
首先,你总得要创建一个TCL文件吧
用文本编辑器把上述代码复制进去,保存为file_name.TCL就可以了
然后在hypermesh 菜单File-> run->tclscript 然后打开那个文件就OK了
弹出:
双击elements
选择单元(图中白色显示)
单击Calculate按钮就可以计算面积了,
共同学习,共同进步!!
免责声明:本文系网络转载或改编,未找到原创作者,版权归原作者所有。如涉及版权,请联系删