hyuanzhu 发表于 2013-1-6 20:22:36

hypermesh二次开发之求取2d单元面积

本帖最后由 hyuanzhu 于 2013-1-6 20:32 编辑

    最近在学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 { == "typechangenotify"} {
      return;
    }
    switch {
      "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 "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 \
    -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 "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 \
    -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 { == "typechangenotify"} {
      return;
    }
    switch {
      "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按钮就可以计算面积了,

共同学习,共同进步!!

suting2008 发表于 2013-1-6 22:28:37

讲得很清楚,学习了,有空我也总结一些例子分享给大家,以共同进步。

lll731462194 发表于 2013-1-6 23:30:08

好例子,谢谢分享

darkhourse 发表于 2013-1-12 22:20:14

学习了,受教了

lll731462194 发表于 2013-1-15 11:57:58

suting2008 发表于 2013-1-6 22:28 static/image/common/back.gif
讲得很清楚,学习了,有空我也总结一些例子分享给大家,以共同进步。

::hwat::utils::GetElementNodes
Finds the nodes of the element.                                       
Syntax        ::hwat::utils::GetElementNodes elemid
Arguments        elemid        The ID of the element.
Returns        A Tcl list containing the nodes of the element if successful , {} if unsuccessful.
Example        ::hwat::utils::GetElementNodes 12.

请问下知道这个命令怎么用么?

lll731462194 发表于 2013-1-15 11:58:43

::hwat::utils::GetElementNodes
Finds the nodes of the element.                                       
Syntax        ::hwat::utils::GetElementNodes elemid
Arguments        elemid        The ID of the element.
Returns        A Tcl list containing the nodes of the element if successful , {} if unsuccessful.
Example        ::hwat::utils::GetElementNodes 12.

请问下知道这个命令怎么用么?

hyuanzhu 发表于 2013-1-17 12:05:05

lll731462194 发表于 2013-1-15 11:58 static/image/common/back.gif
::hwat::utils::GetElementNodes
Finds the nodes of the element.                                       
Syntax        ::hwat::utils::GetElemen ...

加package require hwat;

plastbulate 发表于 2013-4-2 23:21:18

谢谢大神们无私分享,没有找到入门的方法,一直在宏命令里乱转

可乐鸡翅 发表于 2015-11-25 13:31:21

楼主真强大,跪了,讲的真详细
页: [1]
查看完整版本: hypermesh二次开发之求取2d单元面积