//Logo Image
作者:許銘修(2002-08-29);推薦:徐業良(2002-09-04)

撰寫MATLAB程式讀取ANSYS輸出資料檔

經過有限元素分析軟體ANSYS分析後,通常都會將所須要的結果(例如各節點的應力值、位移量等)輸出以便作更進一步的處理。本文主要目的即是在介紹如何撰寫一個適用的MATLAB程式,用以讀取ANSYS所輸出的結果資料,以供作後續處理。

1. 擷取ANSYS輸出資料的方式

1所示為一由ANSYS所輸出之資料檔的部分範例,此範例所輸出的資料為各節點的應力值,包含有第一主應力(S1)、第二主應力(S2)、第三主應力(S3)、應力強度(Stress intensity, SINT),以及等效應力(Equivalent stress, SEQV)

1. ANSYS輸出資料檔範例

***** ANSYS - ENGINEERING ANALYSIS SYSTEM  RELEASE 5.6.2   *****

ANSYS/Mechanical U                               

20000101     VERSION=INTEL NT      01:00:05  AUG 28, 2002 CP=7.120

 2D_CANTILEVER BEAM EXAMPLE                                                   

***** POST1 NODAL STRESS LISTING *****                                      

 

  LOAD STEP=     1  SUBSTEP=     1                                             

   TIME=    1.0000      LOAD CASE=   0                                        

 

    NODE    S1          S2          S3          SINT        SEQV   

       1   215.27      21.573      0.0000      215.27      205.34   

       2   503.83      89.019      0.0000      503.83      465.74   

       4   162.29      19.424      0.0000      162.29      153.51   

       6   208.58      38.839      0.0000      208.58      192.12   

       8   237.35      43.449      0.0000      237.35      218.88   

      10   19.837      0.0000    -0.25204      20.089      19.965   

      12   294.78      0.0000     -26.892      321.68      309.11   

      14   243.68      1.1133      0.0000      243.68      243.13   

      16   217.48      0.0000     -2.2441      219.72      218.61   

 

***** ANSYS - ENGINEERING ANALYSIS SYSTEM  RELEASE 5.6.2   *****

 ANSYS/Mechanical U                               

 20000101      VERSION=INTEL NT    00:27:38  AUG 29, 2002 CP=6.830

 

 2D_CANTILEVER BEAM EXAMPLE                                                    

  ***** POST1 NODAL STRESS LISTING *****                                      

  LOAD STEP=     1  SUBSTEP=     1                                            

   TIME=    1.0000      LOAD CASE=   0                                         

 

    NODE    S1          S2          S3          SINT        SEQV   

   10142   21.027      1.3207      0.0000      21.027      20.399   

   10173   21.319      1.3274      0.0000      21.319      20.688   

   10174   21.454      1.5556      0.0000      21.454      20.720   

   10175   20.755     0.43966      0.0000      20.755      20.539   

   10176   20.900     0.99591      0.0000      20.900      20.420   

   10177   11.539      0.0000     -1.6197      13.159      12.428   

   10178   13.439      0.0000     -1.9825      15.421      14.532   

   10179   15.142      0.0000     -2.3118      17.454      16.420   

   10180   17.266      0.0000     -2.2390      19.505      18.487   

 

 ***** ANSYS - ENGINEERING ANALYSIS SYSTEM  RELEASE 5.6.2   *****

 ANSYS/Mechanical U                               

 20000101    VERSION=INTEL NT      00:27:38  AUG 29, 2002 CP=6.830

 2D_CANTILEVER BEAM EXAMPLE                                                   

  ***** POST1 NODAL STRESS LISTING *****                                       

 

  LOAD STEP=     1  SUBSTEP=     1                                            

   TIME=    1.0000      LOAD CASE=   0                                        

 

    NODE    S1          S2          S3          SINT        SEQV   

   10181   17.464      0.0000     -2.0696      19.533      18.585   

   10182   18.106      0.0000     -2.2822      20.389      19.349   

   10183   17.366      0.0000     -2.3728      19.738      18.666   

   10184   18.888      0.0000     -1.7831      20.672      19.840   

   10185   18.313      0.0000     -1.9109      20.224      19.340    

   10208   17.177      0.0000     -2.6451      19.822      18.641   

   10209   13.755      0.0000     -2.1433      15.898      14.942   

   10210   12.845      0.0000     -1.9575      14.802      13.927   

   10211   12.468      0.0000     -1.8392      14.307      13.482   

 

 MINIMUM VALUES

 NODE        176         176           6         172         172

 VALUE    0.0000    -0.24895     -6.9173     0.48881E-02 0.46942E-02

 

 MAXIMUM VALUES

 NODE          2           2           2           2           2

 VALUE    62.403      13.172      0.0000      62.403      56.971   

擷取ANSYS輸出資料的方式簡單來說,就是由程式一個字串一個字串的讀取資料檔內容,當讀取到指定的特徵字串時,即開始擷取內容。舉例來說,表1中我們所須要的資料是各節點的應力數值,因此當程式讀到字串“SEQV”時,我們知道接下來的資料就是我們所要的,因此可以指定“SEQV”為特徵字串。然而有時只指定一個特徵字串會發生判斷錯誤的狀況,因為特徵字串可能不止出現在一處,因此較為保險的作法,是指定至少兩個以上的連續特徵字串,例如表1的範例,較保險的作法是連續指定“SINT”“SEQV”

相對於特徵字串,有時必須指定一個終止字串來指定資料擷取至何處為止,尤其是當所要擷取的資料分成數個段落時,就必須使用終止字串來作終止的判斷。如表1中所示,應力值資料總共分為三段顯示,因此必須以一終止字串來表示資料擷取完畢,此時可以選擇使用“MINIMUM”作為終止字串。有時我們不知道輸出的資料會被分成幾個段落,因此在擷取資料時都會配合while指令作無窮迴圈的讀取,此時終止字串的判斷就非常要緊,此時可以在while迴圈中加入if指令作為終止迴圈的判斷,而if迴圈的判斷依據就是是否已經讀到終止字串。然而若是所要擷取的資料之後沒有任何字串可作為終止字串,則可以以空集合作為判斷的依據,否則while指令將進入無窮迴圈。

一種比較特殊的狀況是當所要擷取的資料為排列整齊且連續的一群數字,則擷取資料時因為可以利用指令將所有連續的數字一次擷取完畢,直至出現字串為止,因此這一類的狀況下,不須要指定終止字串就可以達到目的。

2. 指令說明

以下將就撰寫資料擷取程式時,相關的MATLAB指令來作說明。

fopen 開啟所要讀取的文件

fopen指令可用於開啟已存在之文件檔案,或是建立一新檔案,表2所示為一使用範例,fem_read為一指標變數,用以表示該開啟檔案,指標變數名稱可以字以給定。Fopen中包含兩個輸入變數,首先必須給予要開啟檔案的路徑、檔名與副檔名,如表2中所示表示將開啟D:\shape_2d\fem_out.out檔案。接著給予工作模式,亦即指定是要讀取檔案(r),或是撰寫檔案(w),此處是要讀取一ANSYS所產生之輸出檔,因此選擇使用“r”

2. fopen指令使用範例

fem_read=fopen('D:\shape_2d\fem_out.out','r');

fscanf 讀取所開啟文件中的資料

fscanf指令用於讀取所開啟文件中的資料,表3所示為fscanf指令的使用範例,data為放置讀取出來的資料的變數,此變數名稱可以自由給定,fscanf指令的輸入變數有三個,第一個為指定所要讀取的文件的指標變數,如表3中所示所要讀取的檔案文件為表2中所開啟的文件。第二個輸入變數為指定要以何種模式讀取資料,常用的模式有兩種:字串(%s)及浮點(%f)。第三個輸入變數為指定要讀取的個數,例如表3中範例(1)所要讀取的為一個字串,因此由fem_read所表示的文件中所讀取道的一個字串,將被儲存於data中;而表3中範例(2)所要讀取的是一個浮點,亦即一個數字,所以所讀取到的數字將被儲存到data中;最後表3中範例(3)並沒有指定所要讀取的浮點個數,因此將讀取至非浮點的資料出現,此種指令使用法可以使用在前一節中所說,指定終止字串的第一類狀況。

舉例來說,若是所要讀取的資料為“1 2 3 4 5”,則以表3範例(1)指令所讀取到的結果為data='1',而且為一字串,必須再以str2num指令將字串轉變為數字才能進行計算。以表3範例(2)指令所讀取到的結果亦為data=[1],然而此已經為數字。以表3範例(3)指令所讀取到的結果則為data=[1 2 3 4 5],且為數字。

3. fscanf指令使用範例

(1) data=fscanf(fem_read, '%s',1)

(2) data=fscanf(fem_read, '%f',1)

(3) data=fscanf(fem_read, '%f')

strcmp 比較兩字串是否相同

strcmp是用來比較兩個字串是否相同的指令,在這裡使用這個指令可以幫助我們找到指定好的特徵字串以及終止字串。表4中所示為strcmp指令的使用範例,若是data = 'SEQV'時,則因為兩個字串相同,所以strcmp指令的結果會輸出1,反之若是data'SEQV'時,則輸出0

4. strcmp指令使用範例

strcmp('SEQV',data)=1            if data = 'SEQV'

strcmp('SEQV',data)=0            if data'SEQV'

3. 程式範例

5所示是一個較為簡單的ANSYS輸出資料範例,由於應力資料是很完整的一整段資料,因此可以使用表3範例(3)指令來擷取,表6即為可適用於表5所列輸出檔之擷取程式範例。由表6所獲得之應力資料結果如表7所示,stress_matrix是一30´1的矩陣,要將其復原為表5中的5´6資料,可以使用for迴圈來達成。

5. 基本之ANSYS輸出檔範例

***** ANSYS - ENGINEERING ANALYSIS SYSTEM  RELEASE 5.6.2   *****

ANSYS/Mechanical U                               

20000101     VERSION=INTEL NT      01:00:05  AUG 28, 2002 CP=7.120

 2D_CANTILEVER BEAM EXAMPLE                                                   

***** POST1 NODAL STRESS LISTING *****                                      

 

  LOAD STEP=     1  SUBSTEP=     1                                            

   TIME=    1.0000      LOAD CASE=   0                                        

 

    NODE    S1          S2          S3          SINT        SEQV   

       1   215.27      21.573      0.0000      215.27      205.34   

       2   503.83      89.019      0.0000      503.83      465.74   

       4   162.29      19.424      0.0000      162.29      153.51   

       6   208.58      38.839      0.0000      208.58      192.12   

       8   237.35      43.449      0.0000      237.35      218.88   

6. 基本之擷取程式範例

fem_read=fopen('D:\shape_2d\fem_out.out','r')

 

data=fscanf(fem_read,'%s',1)

 

while(1)                                                   %無窮迴圈,用以讀取文件中的資料

        if strcmp(data,'SINT')==1                %第一次判斷特徵字串

                data=fscanf(fem_read,'%s',1)

                if strcmp(data,'SEQV')==1       %第二次判斷特徵字串

                        stress_matrix=fscanf(fem_read,'%f')

                        break                               %跳離無窮迴圈

                end;

        else

                data=fscanf(fem_read,'%s',1)

        end;

end;

7. 擷取程式所得之結果

stress_matrix =

    1.0000

  215.2700

   21.5730

         0

  215.2700

  205.3400

    2.0000

  503.8300

   89.0190

         0

  503.8300

  465.7400

    4.0000

  162.2900

   19.4240

         0

  162.2900

  153.5100

    6.0000

  208.5800

   38.8390

         0

  208.5800

  192.1200

    8.0000

  237.3500

   43.4490

         0

  237.3500

  218.8800

8中所示的程式可以用來處理如表1中所示之較複雜之輸出資料,表8中之程式的特點是,對於所須要的資料一個一個的擷取進入矩陣(stress_d)中,而stress_d是以stress_counter來進行計數,因此不論輸出檔的資料分成幾個段落,均可以因為判斷特徵字串'SEQV'而開始擷取資料,並將資料放入N´6stress_d矩陣中,同時也省去了後續資料重新排列的麻煩。由於是處理有分段落的資料,此程式中用了兩個終止字串的判斷,第一個是在判斷每個段落的終點,採用判斷字串出現時為終止點。第二是運用了終止字串'MAXIMUM'來作為最終資料結束的判斷。

在此附加說明第一終止字串判斷處的技巧。由於ANSYS輸出資料常常會在段落的尾端出現一個'1',為何會出現這個'1',目前並不知道,為了避免程式物抓'1',因此使用check_1check_2來作預防,check_1check_2是以字串模式讀取資料,若是所抓到的資料為所要的應力值時,則第一終止字串判斷不會被滿足,因此迴圈不會被終止,反而將check_1check_2資料以str2num指令轉換為數字儲存入stress_d矩陣中。若是check_1抓到'1',則check_2勢必抓到字串,當字串透過str2num指令將會變成是空集合,isempty(str2num(check_2))==1即被滿足,迴圈將會被break指令終止。

8. 可用於擷取表1資料之程式

fem_read=fopen('D:\shape_2d\fem_out.out','r')

buff=fscanf(fem_read,'%s',1);

stress_counter=1;

check_1=[];

stress_d=[];

 

while(1)

        if strcmp(buff,'SEQV')==1

                while(1)

                        check_1=fscanf(fem_read,'%s',1);

                        check_2=fscanf(fem_read,'%s',1);

                       

                        if strcmp(check_1,'1') & isempty(str2num(check_2))==1 | isempty(str2num(check_1))==1        %第一終止字串判斷

                                break;

                        else

                                stress_d(stress_counter,1)=str2num(check_1);%node number

                                stress_d(stress_counter,2)=str2num(check_2);% S1

                                stress_d(stress_counter,3)=fscanf(fem_read,'%f',1);%S2

                                stress_d(stress_counter,4)=fscanf(fem_read,'%f',1);% S3

                                stress_d(stress_counter,5)=fscanf(fem_read,'%f',1);% SINT

                                stress_d(stress_counter,6)=fscanf(fem_read,'%f',1);% SEQV

                                stress_counter= stress_part_counter+1;           

                        end;

                end;

        end;

 

        if strcmp(buff,'MAXIMUM')==1 | strcmp(check_1,'MAXIMUM')==1   

                                                                                                        %第一終止字串判斷

                break;

        end;

       

        buff=fscanf(fem_read,'%s',1);

end;