- 积分
- 35
- 注册时间
- 2004-10-14
- 仿真币
-
- 最后登录
- 1970-1-1
|
楼主 |
发表于 2011-8-14 13:08:17
|
显示全部楼层
来自 加拿大
本帖最后由 whatinrain 于 2011-8-14 13:12 编辑
使用JScript实现最大应力的精确定位
看来我不继续翻译,Matt Sutton的howto系列也没有继续更新, 。其实howto的第5部分早已经出来了,那是对前面4个部分综合应用的一个实例。翻译完howto第 4部分的时候也想找个例子实际检验一下,正好J版的帖子Mechanical中获取最大结果值节点坐标和编号的方法(http://forum.simwe.com/viewthread.php?tid=996929)出现了。要使用脚本编程来自动实现一些功能,要么是简单重复的功能,要么是复杂的需要多次鼠标点击键盘输入的才能实现,而J版要描述的方法正好符合第二种情况。
思路。
在J版的方法中,1,输入一个probe,2,在最大值的附近点取一个坐标(coordinate),3,snap to mesh nodes,4,选取要显示的结果类型,5,evaluate。
要用脚本JScript来代替用户输入,插入一个probe好办,选取一个坐标可能没有那么简单。仔细查看了在Mechanical中的操作过程,当点取工具栏上的坐标(Coordinate)然后选取的geometry,并不是vertex,不是很明白是什么类型,但是选取后在probe的 geometry中可以应用。Probe的location method中还有一个选项是coordinate system,而对于如何创建一个坐标系已经有代码了(http://forum.simwe.com/viewthread.php?tid=940832),那就准备用这个了。问题是原点坐标从哪里来?
第一个想法就是导出所有stress的数据,导出前确定一并导出节点号和节点坐标,然后在导出的文件中找出最大值。但是如果导出的文件中包含了很多节点数据,那光是查找出最大值就要花很多时间。
第二个想法是用*get等APDL的命令通过 restart来获得,这样也不用重新求解。问题是缺省情况下,restart control中retain files after full solve是为No的。也就是说如果求解完了,插入了APDL命令,然后想用restart的时候发现没有支持文件存在。直接的APDL不行,想到了 JPDL,用JScript封装的APDL命令,但怎么试都不行,连初始的对象都没有办法创建。于是寻求了一下技术支持,答曰早不支持JPDL了。不支持了为什么还封装在安装包里呀,浪费我硬盘呀,有木有!直接问技术支持如何用JScript来获得最大应力的节点号及坐标,此帖发布之时还没有回应。
于是非常纠结地回到了第一个想法。虽然有可能会在搜查最大应力数据的时候花很长时间,但终究也是一个解决方法。就准备用第一个想法了。
于是更新后的完整思路如下,
1,选定应力数据项,求解过的;
2,导出数据,不是excel file而是text file,方便计算机上没有安装excel的使用;
3,找到第一个最大应力值,返回节点号和节点坐标;
4,根据节点坐标创建坐标系,节点号可以成为新建坐标系的名称;
5,插入一个probe,并使用创建的坐标系;
6,evaluate。
编程。
这段程序断断续续写了一个星期,如果没有microsoft visual studio 2010(mvs)这个调试工具,完成的日期可能是遥遥无期。在AWB 11.0的时候有写过一些代码,但是这些代码在AWB 13.0中并不能顺利运行,通过mvs才知道很多对象、属性和方法都改变了。最不能令人忍受的是还没有文档,一切都是在摸黑中进行,mvs也只不过是一个手电筒而已。Matt Sutton的脚本编程howto系列前面4个部分,可以算是另外一个手电筒。有了两个手电筒,也勉强可以行走了。
1,在dsstringtable.xml中搜索Mechanical中工具栏或菜单项上字符串,并找到对应的ID。有时候会出现搜索的字符串出现在多个地方并有多个ID对应,如果不能准备判断就只能一个个查看了;
2,在dscontextmenu.xml中搜索ID,并找到对应的函数;
3,搜索函数出现的js文件并找到函数的定义,大多数函数出现在 DSMenuScript.js中;
4,函数的定义中会出现一些常量,大多数常量可以在DSConstants.js中找到;
5,最难搞定的是对象的获得和引用,这个需要mvs出马。在debugger状态下,可以在mvs中查看对象以及所属的属性和方法;
6,Detail of Probe中有个Location Method,正好Probe对象有个属性是LocationMethod,界面上有Result Selection,于是猜有个属性应该是ResultSelection,但是找不到,试着运行也不行,用mvs一看,对应的属性应该是 DisplayFilter,跟界面上的根本不一样;
7,代码已附,注释已加。
结果。
在类似于J版的模型上测试代码运行,运行速度很快(这么小的模型能不快吗,:lol ),结果也不错。
1,全自动后台处理,过程中无需用户输入;
2,最大值的出现的位置无论是表面还是内部都是无差别处理。
对于只是提供一个解决方法来说,到这里就可以收工了。而如果对于应用来说,可能还会有以下问题,
1,对于大模型最大值的搜索速度能满足吗?如果不行,修改算法或通过其他的方法获得最大值对应的节点信息?
2,和J版的snap to mesh nodes方法比,这个方法可能会有插值的问题,虽然是对应的坐标是一样的。曾惊鸿一瞥地看到通过代码得到的probe结果和通过的snap to mesh nodes得到的结果相差了0.001,而坐标是完全一样的。虽然后面测试再也没有看到这样的结果,但还是有这样的怀疑。
后记。
碰到同事有点小得意地说编了这么个程序可以自动得到结果,同事盯着我看了3秒说,这有什么用呢?当时就石化加凌乱了,一个星期呀,这让我情何以堪呀。
谨以我的第1000贴纪念我在simwe上的日日夜夜。
- // JScript source code
- //常量声明
- var id_kProbeStress = 1;
- var id_AnswerSet = 107;
- var id_COORDINATE_SYSTEM_SELECTION = 1;
- var id_ShowMaxPrincipal = 11;
- var id_ShowEquivalent = 13;
- var id_EquivalentStress = 1;
- var id_MaximumPrincipalStress = 2;
- var ForReading = 1;
- var ForWriting = 2;
- var ForAppending = 8;
- var MBBID_IDNO = 7;
- var MBBID_IDCANCEL = 2;
- var id_Result = 520;
- InsertProbeStressWithCS();
- function InsertProbeStressWithCS()
- {
- //debugger在正式运行的时候屏蔽,调试的时候打开
- //debugger;
- var probeResult = null;
- var answerSetObj = null;
- var stressObj=null;
- var selObj=null;
- //选择一个项,判断是不是结果,是Equivalent Stress还是Maximum Principal Stress
- selObj=DS.Tree.FirstActiveObject;
-
- if (selObj.Class==id_Result)
- {
- if (!(selObj.ResultType==id_EquivalentStress||selObj.ResultType==id_MaximumPrincipalStress))
- {
- WBScript.Out( "Please select one stress item.", true );
- return;
- }
- }
- else
- {
- WBScript.Out( "Please select one stress item.", true );
- return;
- }
-
-
- //弹出对话框提示选择输出节点位置
- var Text="Please make sure the option of Export in Mechanical is YES\nfor include node number/node location.";
- var Caption="Message";
- var buttonType = 1; // Yes|No|Cancel;
- buttonType += 32; // Icon Questionmark
- var retVal = WBScript.Out(Text, true, Caption, buttonType, WB.hWnd);
- if (retVal==MBBID_IDCANCEL)
- return;
-
- //确定AnswerSet对象
- answerSetObj = selObj.Parent;
- //确定branch对象
- var branchObj = DS.Tree.FirstActiveBranch;
- //确定是否求解过
- if (!selObj.IsSolved)
- {
- WBScript.Out("Please solve/evaluate the stress item first",true);
- return;
- }
-
- //查找最大应力值并返回对应节点信息
- var maxStress=new Array(5);
- maxStress = GetMaxResult(selObj);
-
- //没有找到最大应力值
- if (maxStress[0]==0)
- {
- WBScript.Out("Cannot find node info of Max. Stress",true);
- return;
- }
-
- //使用返回的节点信息创建坐标系
- var stressCS = CreateCoordinateSystem(branchObj, "Node" + maxStress[0], parseFloat(maxStress[1]), parseFloat(maxStress[2]), parseFloat(maxStress[3]));
-
- //插入一个stress probe
- probeResult = answerSetObj.AddResultProbe(SM, id_kProbeStress);
- if( !probeResult )
- {
- WBScript.Out( "Can not Find Object", true );
- return;
- }
-
- //清空选择管理器
- SM.Clear();
- //把probe的定位方法选择为坐标系
- probeResult.LocationMethod=id_COORDINATE_SYSTEM_SELECTION;
- //要使用坐标系的内部ID,而不是ansys的坐标系号码
- probeResult.LocationCoordinateSystem = stressCS.ID;
- //根据第一个所选的应力类型自动改变probe的结果类型,并修改对应名称
- if (selObj.ResultType == id_EquivalentStress)
- {
- probeResult.DisplayFilter = id_ShowEquivalent;
- probeResult.Name = "Equivalent Stress Probe @Node " + maxStress[0];
- }
- if (selObj.ResultType == id_MaximumPrincipalStress)
- {
- probeResult.DisplayFilter = id_ShowMaxPrincipal;
- probeResult.Name = "Max. PrincipalStress Probe @Node " + maxStress[0];
- }
-
- //evaluate
- answerSetObj.FindAnswers();
- //更新树
- DS.Script.fillTree();
- }
- //在输出文件中查找最大应力值并返回对应节点信息
- function GetMaxResult(resObj)
- {
- //给定一个文件名作为输出文件名
- var fileName = "c:\\temp\\resulttoexcel.txt";
- //导出所选结果项的数据
- var fileText = resObj.CreateTabbedFile(fileName);
- //创建一个文件对象
- var fso = new ActiveXObject("Scripting.FileSystemObject");
- //创建一个文件
- f = fso.CreateTextFile(fileName, true);
- //写入文件
- f.Write(fileText);
- //关闭文件
- f.Close();
- //打开这个文件
- f = fso.OpenTextFile(fileName, ForReading);
- var tmpData = new Array(5);
- var maxData = new Array(0,0,0,0,0);
- var i=0;
- var r;
- //把第一行的抬头跳过去
- f.SkipLine();
- while (!f.AtEndOfStream)
- {
- r = f.ReadLine();
- //通过制表符提取数据,\t是制表符,/\t/是正则表达式
- tmpData = r.split(/\t/);
- //把碰到的最大的数据记录下
- if (parseFloat(tmpData[4]) > parseFloat(maxData[4]))
- {
- maxData = tmpData;
- }
- }
- f.Close();
- return maxData;
- }
- //创建坐标
- function CreateCoordinateSystem(branchObj,csName,csX,csY,csZ)
- {
- //获得CoordinateSystemGroup对象
- var CurrentModels = branchObj.Model;
- if (CurrentModels.CoordinateSystemGroup)
- curCoorGroup = CurrentModels.CoordinateSystemGroup;
- else
- curCoorGroup = CurrentModels.AddCoordinateSystemGroup();
- // 插入一个新坐标系
- var currCoor = curCoorGroup.AddCoordinateSystem(SM);
- //用节点号作为坐标系名
- currCoor.Name = csName;
- //原点
- currCoor.OriginAlignment=0;
- currCoor.OriginXLocation=csX;
- currCoor.OriginYLocation=csY;
- currCoor.OriginZLocation=csZ;
- //cartesian system
- currCoor.CoordinateSystemType = 0;
- currCoor.AxisPriority = 0;
- currCoor.PrimaryAxis = 1;
- currCoor.SecondaryAxis = 2;
- currCoor.PrimaryAxisAlignment = 2;
- currCoor.SecondaryAxisAlignment = 3;
- return currCoor;
- }
复制代码 |
本帖子中包含更多资源
您需要 登录 才可以下载或查看,没有账号?注册
×
评分
-
2
查看全部评分
-
|