转换Ansys日志文件命令流的小工具:AnsysCommandParser
AnsysCommandParser是一个用于清理和转换Ansys日志文件(.log文件),以生成等价的Ansys命令流的小工具。
主要功能:
1.删除"/auto","/dist","/replot"之类因图形界面操作所产生的“无用指令”(对建模和计算本身无影响的指令);
目前程序中所删除的指令包括:
"/dist",
"/replot", "/rep", "/replo",
"/focus", "/foc",
"kplot", "lplot", "aplot", "gplot", "eplot",
"/user",
"/pnum",
"/input",
"/number", "/num",
"/zoom",
"chkmsh",
"/auto"
2.将图形界面选择操作所产生的选择操作指令,如:
FLST,5,8,4,ORDE,5
FITEM,5,3
FITEM,5,5
FITEM,5,-7
FITEM,5,46
FITEM,5,-49
CM,_Y,LINE
LSEL, , , ,P51X
CM,_Y1,LINE
CMSEL,,_Y
!*
LESIZE,_Y1, , ,10, , , , ,1
转换为等价,但更加简洁、可读性更好、更适合手工输入的选择操作指令,如:
lsel,s,line,,3
lsel,a,line,,5,7
lsel,a,line,,46,49
lesize,all,,,10,,,,,1
目前程序所转换的选择操作包括:节点选择("nsel")、单元选择("esel")、 关键点选择("ksel")、线选择("lsel")、面选择("asel")
使用说明:
1.解压压缩包到任意目录;
2.启动AnsysCmdParser.exe;
3.将从Ansys日志文件(.log文件)复制出来的命令流记录复制到程序左侧的文本框中,然后点击“Parse”按钮;
4.复制右侧文本框中的生成的内容到你的目标位置(Ansys命令窗口,自己的命令流文件等等)。由于执行第3步后,生成的命令流已自动复制到剪贴板,所以***没有必要手动的进行复制操作***,直接粘贴到目标位置即可。
5.点击Clear按钮可清除两个文本框中的内容。
示例:
下面这段ANSYS日志文件中的命令流:
EPLOT
ALLSEL,ALL
LPLOT
/AUTO,1
/REP,FAST
/ZOOM,1,RECT,0.0599766,0.0983278 ,0.604427072832 ,0.0105351165784
FLST,2,2,4,ORDE,2
FITEM,2,57
FITEM,2,-58
LCCAT,P51X
FLST,2,2,4,ORDE,2
FITEM,2,99
FITEM,2,107
LCCAT,P51X
FLST,2,2,4,ORDE,2
FITEM,2,97
FITEM,2,105
LCCAT,P51X
FLST,2,2,4,ORDE,2
FITEM,2,55
FITEM,2,-56
LCCAT,P51X
FLST,5,8,5,ORDE,4
FITEM,5,31
FITEM,5,-36
FITEM,5,44
FITEM,5,-45
CM,_Y,AREA
ASEL, , , ,P51X
CM,_Y1,AREA
CHKMSH,'AREA'
CMSEL,S,_Y
!*
AMESH,_Y1
!*
CMDELE,_Y
CMDELE,_Y1
CMDELE,_Y2
!*
LPLOT
/DIST,1,1.08222638492,1
/REP,FAST
/AUTO,1
/REP,FAST
/ZOOM,1,RECT,-0.0313506,0.3301 ,0.681703919018 ,0.126421398941
FLST,5,8,4,ORDE,5
FITEM,5,3
FITEM,5,5
FITEM,5,-7
FITEM,5,46
FITEM,5,-49
CM,_Y,LINE
LSEL, , , ,P51X
CM,_Y1,LINE
CMSEL,,_Y
!*
LESIZE,_Y1, , ,10, , , , ,1
经过转换后,得到:
allsel,all
lsel,s,line,,57,58
lccat,all
lsel,s,line,,99
lsel,a,line,,107
lccat,all
lsel,s,line,,97
lsel,a,line,,105
lccat,all
lsel,s,line,,55,56
lccat,all
asel,s,area,,31,36
asel,a,area,,44,45
amesh,all
lsel,s,line,,3
lsel,a,line,,5,7
lsel,a,line,,46,49
lesize,all,,,10,,,,,1
源代码(主体部分)
#pragma once #include "stdafx.h" #include "resource.h" #include <atldataobj.h> // CClipboard class by Bjarke Viksoe #include <vector> using std::vector; #include <string> using std::wstring; #include <sstream> using std::wistringstream; using std::wostringstream; #include <iostream> #include <boost/algorithm/string.hpp> #include <tuple> using std::tuple; using std::make_tuple; #include <array> using std::array; const wchar_t COMMA = L','; const wstring LINEEND = L"\r\n"; array<wstring,5> SelCmdNames = { L"nsel", L"esel", L"ksel", L"lsel", L"asel" }; array<wstring,5> SelItems = { L"node", L"elem", L"kp", L"line", L"area" }; array<wstring,20> IgnoredCmds = { L"/dist", L"/replot", L"/rep", L"/replo", L"/focus", L"/foc", L"kplot", L"lplot", L"aplot", L"gplot", L"eplot", L"/user", //L"/com", L"/pnum", L"/input", L"/number", L"/num", L"/zoom", L"chkmsh", L"/auto" }; bool IsStrStartWith(const wstring& str, const wstring& start) { return str.substr(0,start.size())==start; } template< typename T > bool StrToNum(const std::wstring& str, T& num) { std::wistringstream iss(str); return !(iss>>num).fail(); } const COLORREF EDIT_BKGND_COLOR = RGB(204,232,207); class CMainDialog : public CDialogImpl<CMainDialog>, public CMessageFilter, public CWinDataExchange<CMainDialog>, public CDialogResize<CMainDialog> { public: enum { IDD = IDD_MAIN }; typedef CMainDialog _thisClass; typedef CDialogResize<_thisClass> _baseDlgResize; BEGIN_MSG_MAP(_thisClass) MSG_WM_CTLCOLOREDIT(OnCtlColorEdit) COMMAND_HANDLER_EX(IDC_BUTTON_PARSE, BN_CLICKED, OnBnClickedParse) COMMAND_HANDLER_EX(IDC_BUTTON_CLEAR, BN_CLICKED, OnBnClickedClear) COMMAND_ID_HANDLER_EX(IDCANCEL,OnCancel) MSG_WM_INITDIALOG(OnInitDialog) MSG_WM_DESTROY(OnDestroy) CHAIN_MSG_MAP(_baseDlgResize) END_MSG_MAP() BEGIN_DDX_MAP(_thisClass) DDX_CONTROL_HANDLE(IDC_EDIT_INPUT, m_EditInput) DDX_CONTROL_HANDLE(IDC_EDIT_OUTPUT, m_EditOutput) END_DDX_MAP() BEGIN_DLGRESIZE_MAP(_thisClass) DLGRESIZE_CONTROL(IDC_BUTTON_PARSE, DLSZ_MOVE_X|DLSZ_MOVE_Y) DLGRESIZE_CONTROL(IDC_BUTTON_CLEAR, DLSZ_MOVE_X|DLSZ_MOVE_Y) BEGIN_DLGRESIZE_GROUP() DLGRESIZE_CONTROL(IDC_EDIT_INPUT, DLSZ_SIZE_X) DLGRESIZE_CONTROL(IDC_EDIT_OUTPUT, DLSZ_SIZE_X) END_DLGRESIZE_GROUP() DLGRESIZE_CONTROL(IDC_EDIT_INPUT, DLSZ_SIZE_Y) DLGRESIZE_CONTROL(IDC_EDIT_OUTPUT, DLSZ_SIZE_Y) END_DLGRESIZE_MAP() public: virtual BOOL PreTranslateMessage(MSG* pMsg) { return CWindow::IsDialogMessage(pMsg); } public: BOOL OnInitDialog(CWindow /*wndFocus*/, LPARAM /*lInitParam*/) { // Initialize dialog resize DlgResize_Init(); // Bind controls to variables DoDataExchange(FALSE); InitIgnoredCmdList(); InitControls(); ResizeClient(800,600); CenterWindow(); return TRUE; } void InitControls() { CLogFont lf; TCHAR fontName[] = _T("Courier New"); SecureHelper::strcpy_x(lf.lfFaceName,32,fontName); lf.lfHeight = 18; m_FontEdit.CreateFontIndirect(&lf); m_EditInput.SetFont(m_FontEdit); m_EditInput.SetLimitText(0); m_EditOutput.SetFont(m_FontEdit); m_EditOutput.SetLimitText(0); m_BrushEdit.CreateSolidBrush(EDIT_BKGND_COLOR); ATL_CHECK_HANDLE(m_BrushEdit); } void InitIgnoredCmdList() { for (auto it=SelCmdNames.cbegin();it!=SelCmdNames.cend();it++) { m_vecIgnoredSelCmd.push_back(make_tuple( *it, 3, L"p51x" )); } m_vecIgnoredSelCmd.push_back(make_tuple( L"cm", 0, L"_y" )); m_vecIgnoredSelCmd.push_back(make_tuple( L"cmsel", 1, L"_y" )); m_vecIgnoredSelCmd.push_back(make_tuple( L"cmdele", 0, L"_y" )); } void OnDestroy() { } void OnBnClickedParse(UINT /*uNotifyCode*/, int /*nID*/, CWindow /*wndCtl*/) { Parse(); } void OnBnClickedClear(UINT /*uNotifyCode*/, int /*nID*/, CWindow /*wndCtl*/) { m_EditInput.SetWindowText(_T("")); m_EditOutput.SetWindowText(_T("")); } void OnCancel(UINT /*uNotifyCode*/, int /*nID*/, CWindow /*wndCtl*/) { DestroyWindow(); PostQuitMessage(0); } HBRUSH OnCtlColorEdit(CDCHandle dc, CEdit edit) { dc.SetBkColor(EDIT_BKGND_COLOR); return m_BrushEdit; } private: enum AnsysSelType { UnknownType = 0, NodeNumber = 1, ElementNumber, KeypointNumber, LineNumber, AreaNumber }; enum AnsysCmdType { OrdinaryCmd, FLST, FITEM, IgnoredCmd, IgnoredSelCmd, DeleLccaCmd, Comment, BlankLine }; void Parse() { ATL::CString text; m_EditInput.GetWindowText(text); wstring inputStr = text; ParseAnsysCmd(inputStr); } void ParseAnsysCmd(const wstring& inputStr) { ATLASSERT(inputStr.size()>0); wostringstream oss; AnsysSelType selType = UnknownType; AnsysCmdType lastCmdType = OrdinaryCmd; AnsysCmdType thisCmdType = OrdinaryCmd; wistringstream iss(inputStr); wstring cmdLine; while (std::getline(iss,cmdLine)) { wstring cmdName; vector<wstring> args; boost::trim(cmdLine); if (cmdLine.empty()) // blank line { thisCmdType = BlankLine; } else if (cmdLine[0]==L'!') // comments { thisCmdType = Comment; } else { boost::to_lower(cmdLine); GetCmdName(cmdLine,cmdName); if (IsIgnoredCmd(cmdName)) { ATLASSERT(lastCmdType!=FLST); thisCmdType = IgnoredCmd; } else { GetCmdArgs(cmdLine,args); if (IsIgnoredSelCmd(cmdName,args)) // ignored select command { ATLASSERT(lastCmdType!=FLST); thisCmdType = IgnoredSelCmd; } else if (cmdName == L"flst") // "FLST" command { ATLASSERT(lastCmdType!=FLST); thisCmdType = FLST; int num = 0; bool res = StrToNum(args[2],num); ATLASSERT(res && 1<=num && num<=5); selType = (AnsysSelType)num; } else if (cmdName == L"fitem") // "FITEM" command { ATLASSERT((lastCmdType==FLST) || (lastCmdType==FITEM)); thisCmdType = FITEM; int selNum = 0; bool res = StrToNum(args[1],selNum); ATLASSERT(res && selNum!=0); if (selNum > 0) { const wstring& cmd = SelCmdNames[selType-1]; wstring type = (lastCmdType==FLST)? L"s":L"a"; const wstring& item = SelItems[selType-1]; oss <<LINEEND <<cmd<<COMMA<<type<<COMMA<<item<<COMMA<<COMMA<<selNum; } else // if selNum < 0 { oss<<COMMA<<(-selNum); } } else if (cmdName == L"*set" && IsStrStartWith(args[1],L"lsinqr")) { ATLASSERT(lastCmdType!=FLST); thisCmdType = DeleLccaCmd; const int JUMP_LINES = 13; for (int i=0;i<JUMP_LINES;++i) std::getline(iss,cmdLine); oss <<LINEEND<<LINEEND <<L"lsel,s,lcca"<<LINEEND <<L"ldele,all"<<LINEEND; } else // other ordinary command { ATLASSERT(lastCmdType!=FLST); thisCmdType = OrdinaryCmd; oss<<LINEEND<<cmdName; // replace "p51x" and "_yN" label with "all", // then output all args std::for_each(args.begin(),args.end(),[&oss](wstring& arg){ if (IsStrStartWith(arg,L"p51x")||IsStrStartWith(arg,L"_y")){ arg = L"all"; } oss<<COMMA<<arg; }); } } lastCmdType = thisCmdType; continue; // we have output this command here, // then we need to process the next one directly } ATLASSERT(thisCmdType==BlankLine || thisCmdType==Comment); if (lastCmdType==FITEM || lastCmdType==OrdinaryCmd) { oss<<LINEEND; } lastCmdType = thisCmdType; } m_EditOutput.SetWindowText(oss.str().c_str()); CClipboard clipBoard(NULL); ATLASSERT(clipBoard.IsOpen()); clipBoard.Empty(); clipBoard.SetUnicodeTextData(oss.str().c_str()); } bool IsSelCmd(const wstring& cmdName) { return std::any_of(SelCmdNames.cbegin(),SelCmdNames.cend(), [&cmdName](const wstring& name) { return cmdName==name; }); } bool IsIgnoredCmd(const wstring& cmdName) { return std::any_of(IgnoredCmds.cbegin(),IgnoredCmds.cend(), [&cmdName](const wstring& name) { return cmdName==name; }); } bool IsIgnoredSelCmd(const wstring& cmdName, const vector<wstring>& args) { return std::any_of(m_vecIgnoredSelCmd.cbegin(),m_vecIgnoredSelCmd.cend(), [&cmdName,&args](const tuple<wstring,int,wstring>& t)->bool { const wstring& name = std::get<0>(t); int i = std::get<1>(t); const wstring& arg = std::get<2>(t); return (cmdName==name) && (args.size()>i) && IsStrStartWith(args[i],arg); }); } void GetCmdName(const wstring& cmdLine, wstring& cmdName) { ATLASSERT(!cmdLine.empty() && cmdName.empty()); std::wistringstream iss(cmdLine); std::getline(iss,cmdName,COMMA); boost::trim(cmdName); ATLASSERT(!cmdName.empty()); } void GetCmdArgs(const wstring& cmdLine, vector<wstring>& args) { ATLASSERT(!cmdLine.empty() && args.empty()); std::wistringstream iss(cmdLine); wstring cmdName; std::getline(iss,cmdName,COMMA); wstring arg; while (std::getline(iss,arg,COMMA)) { boost::trim(arg); args.push_back(arg); } } private: CFont m_FontEdit; CEdit m_EditInput; CEdit m_EditOutput; CBrush m_BrushEdit; vector<tuple<wstring,int,wstring>> m_vecIgnoredSelCmd; };