【Abaqus Python】Abaqusのマクロの使い方

# はじめに



Abaqusを使用している時、どうしても同じような作業をすることがめんどくさくなることがあります。
そんな時、マクロを使って動かすという方法があるのですが、どうも調べてもやり方を説明しているサイトが見当たりません。
そのため、使い方を1から解説していこうと思います。




# マクロの言語はPython2.7


Abaqusのマクロに使用されているプログラミング言語は`Python`です。
最近では人気があり、とっつきやすいですが一つだけ問題があります。
Pythonは Pythonでも、`Python2.7`なのです。現在主流の`Python3系`とは**互換性がない**古いバージョンです。
互換性がないといっても、大部分の文法は同じなので、何か動かないと思ったらバージョンの違いを疑ってみてください。
ちなみに私の場合はcsvライブラリのバージョンが古く書き方が変わっていて動かなかったというものがあります。

正確なPythonのバージョンが知りたい場合は、Abaqusの下の黄色いアイコンをクリックするとPythonを対話モードで使用できるので、以下のように入力してみてください。
私の使用しているAbaqus2022ではバージョンは`2.7.15`でした。


```python
import sys
print(sys.version)
#2.7.15 (default, Oct 16 2021, 07:27:26) [MSC v.1928 64 bit (AMD64)]
```

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/993303/82c8dc67-ee7f-032c-fd3b-17eccf5af14f.png)



# マクロの使い方

「ファイル」→「マクロマネージャ」を押すことでマクロマネージャのウィンドウが表示されます。
![image.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/993303/dd7ca76b-11e2-de96-4982-bc548d257b03.jpeg)

初めて使う場合は、何もマクロは存在しません。
「作成」を押すと、「マクロの作成」というウィンドウが出てきて、保存先のディレクトリを選択できるようになります。
`ワーク`だとインストール時に指定したワーキングディレクトリ（ジョブファイルなどが生成されるフォルダ）に保存されます。
`ホーム`はWindowsだと`C¥:Users¥ユーザー名¥`のディレクトリに保存されます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/993303/e0aefb10-dc31-e613-a7ca-08219033f273.png)


ここで、「続ける」を押すことでマクロの記録が表示され「マクロの記録」というウィンドウが出てきます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/993303/4131b927-507a-5170-d22b-89b84c001c78.png)


そして、`記録中`のまま自動化させたいことを一通り実際にAbsqus内で操作し、すべて終わったら「記録の中止」をクリックします。
すると、マクロが表示され、どこのディレクトリのどのファイルに保存されたかも下に表示されます。

その後、マクロを選択して「実行」を押すと保存した内容が実行されます。
これでマクロの作成及び実行の方法は以上です。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/993303/066eb8d1-9616-4363-b22c-fc796d9c92d1.png)







# マクロファイルの編集

Abaqus CAE上で記録した操作だけでなく、Pythonでできる反復実行などをしたいときは、マクロファイルを編集します。
マクロが保存されているファイル名は`abaqusMacros.py`で、Abaqusからは自動的にこのファイル名のプログラムのみ見ているようです。
保存場所は、先に書いたように`ワーク`だとインストール時に指定したワーキングディレクトリ（ジョブファイルなどが生成されるフォルダ）に、`ホーム`はWindowsだと`C¥:Users¥ユーザー名¥`のディレクトリです。





何も操作せずにマクロを保存した際にできたマクロファイルの中身が以下になります。
基本的にファイルの上部で3つimportしています。
そして、各マクロ名が関数名となった関数内では、Abaqusを動かすためのライブラリをインポートしています。こちらは、CAEやViewerなどマクロファイルを作った環境によって異なります。


実際に何か記録した場合、`pass`の部分に色々書かれていきます。
自分で1から書かなければいけないということはないので安心してください。




```abaqusMacros.py
# -*- coding: mbcs -*-
# Do not delete the following import lines
from abaqus import *
from abaqusConstants import *
import __main__

def Macro1():
    import section
    import regionToolset
    import displayGroupMdbToolset as dgm
    import part
    import material
    import assembly
    import step
    import interaction
    import load
    import mesh
    import optimization
    import job
    import sketch
    import visualization
    import xyPlot
    import displayGroupOdbToolset as dgo
    import connectorBehavior
    pass
```





# マクロファイルおすすめ


## エラー文の出力
マクロを作っていると、どこかが間違っていて動かないことがあります。
デフォルトのまま書いていると、Abaqus上でエラーが発生しても間違っていることしか表示されず、プログラムのエラーメッセージは表示されません。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/993303/43c942c7-b1f7-1064-90c7-bc9a5399eebf.png)


そこで、エラーメッセージを表示させるために、以下のように`try` `except` `traceback`を書くことを強くお勧めします。


```abaqusMacros.py
try:
   #プログラムの内容
except:
   import traceback
   print(traceback.format_exc())
```

そうすると、このように下部でエラーメッセージが表示されるようになります。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/993303/9564f326-0dd3-4fde-5a62-c410dc965302.png)




## マクロを途中で止める

マクロを途中まで実行して止めたいときは、以下のように関数を終了させればいいです。

```python
import sys
sys.exit()
```



## 文字列のプリント

`print()`を使用することで、CAEの下部に文章を表示できます。


# マクロ作成例　複数パートの作成

ここでは、実際にマクロファイルを分析しながら作っていく方法を紹介します。

## CAE上で直方体の作成

とりあえず、3次元で直方体を作っていきましょう。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/993303/f70f01e7-be5b-c61c-3231-7b1bf5b08cf5.png)


![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/993303/8848803d-2a36-ec65-4d0d-0b2f947679ca.png)


![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/993303/47d1ffe1-088f-328e-76ab-ac004b0a8930.png)


この動作を保存したマクロが以下になります。

```abaqusMacros.py
# -*- coding: mbcs -*-
# Do not delete the following import lines
from abaqus import *
from abaqusConstants import *
import __main__

def Macro3():
    import section
    import regionToolset
    import displayGroupMdbToolset as dgm
    import part
    import material
    import assembly
    import step
    import interaction
    import load
    import mesh
    import optimization
    import job
    import sketch
    import visualization
    import xyPlot
    import displayGroupOdbToolset as dgo
    import connectorBehavior
    s1 = mdb.models['Model-1'].ConstrainedSketch(name='__profile__', 
        sheetSize=200.0)
    g, v, d, c = s1.geometry, s1.vertices, s1.dimensions, s1.constraints
    s1.setPrimaryObject(option=STANDALONE)
    s1.rectangle(point1=(0.0, 0.0), point2=(20.0, 5.0))
    session.viewports['Viewport: 1'].view.setValues(nearPlane=180.565, 
        farPlane=196.559, width=46.8405, height=45.3934, cameraPosition=(15.7, 
        -10.547, 188.562), cameraTarget=(15.7, -10.547, 0))
    p = mdb.models['Model-1'].Part(name='Part-1', dimensionality=THREE_D, 
        type=DEFORMABLE_BODY)
    p = mdb.models['Model-1'].parts['Part-1']
    p.BaseSolidExtrude(sketch=s1, depth=20.0)
    s1.unsetPrimaryObject()
    p = mdb.models['Model-1'].parts['Part-1']
    session.viewports['Viewport: 1'].setValues(displayedObject=p)
    del mdb.models['Model-1'].sketches['__profile__']
```


## マクロの分析

このマクロを分析すると、それぞれこのようなことをしていると推測されます。
なお、おそらく**マクロファイル上で全角文字を使用するとエラーになる**ので注意してください。
(間違いがある可能性があるので注意)
なお、以下`import`文はすべて省略します。


```abaqusMacros.py
    #スケッチの画面s1の指定
    s1 = mdb.models['Model-1'].ConstrainedSketch(name='__profile__', 
        sheetSize=200.0)
    #s1からオブジェクトの呼び出し（後で見やすいように）
    g, v, d, c = s1.geometry, s1.vertices, s1.dimensions, s1.constraints
    #不明
    s1.setPrimaryObject(option=STANDALONE)

    #(0.0, 0.0), (20.0, 5.0)を対角とした四角形をs1に作成
    s1.rectangle(point1=(0.0, 0.0), point2=(20.0, 5.0))

    #スケッチ上での拡大縮小など
    session.viewports['Viewport: 1'].view.setValues(nearPlane=180.565, 
        farPlane=196.559, width=46.8405, height=45.3934, cameraPosition=(15.7, 
        -10.547, 188.562), cameraTarget=(15.7, -10.547, 0))
    
    #CAE上では最初に設定したパートの作成の内容
    p = mdb.models['Model-1'].Part(name='Part-1', dimensionality=THREE_D, 
        type=DEFORMABLE_BODY)

    #'Part-1'のパートの指定
    p = mdb.models['Model-1'].parts['Part-1']
    #四角形を描写したスケッチs1を奥行20で押し出し
    p.BaseSolidExtrude(sketch=s1, depth=20.0)

    #不明
    s1.unsetPrimaryObject()

    #CAE上で#'Part-1'のパートの表示
    p = mdb.models['Model-1'].parts['Part-1']
    session.viewports['Viewport: 1'].setValues(displayedObject=p)

    #スケッチの削除
    del mdb.models['Model-1'].sketches['__profile__']
```


## マクロの編集

分析したマクロをもとに、新しいマクロを作ろうと思います。
例えば、forループを使用して直方体のパートを4つ作成しようと思います。


### 1.try exceptの追加
まず、`try` `except` `traceback`を追加します。
これでマクロを編集していてエラーが出ても、エラー文が出るようになってはかどります。


```python
    try:
        s1 = mdb.models['Model-1'].ConstrainedSketch(name='__profile__', 
            sheetSize=200.0)
        g, v, d, c = s1.geometry, s1.vertices, s1.dimensions, s1.constraints
        s1.setPrimaryObject(option=STANDALONE)
        s1.rectangle(point1=(0.0, 0.0), point2=(20.0, 5.0))
        session.viewports['Viewport: 1'].view.setValues(nearPlane=180.565, 
            farPlane=196.559, width=46.8405, height=45.3934, cameraPosition=(15.7, 
            -10.547, 188.562), cameraTarget=(15.7, -10.547, 0))
        p = mdb.models['Model-1'].Part(name='Part-1', dimensionality=THREE_D, 
            type=DEFORMABLE_BODY)
        p = mdb.models['Model-1'].parts['Part-1']
        p.BaseSolidExtrude(sketch=s1, depth=20.0)
        s1.unsetPrimaryObject()
        p = mdb.models['Model-1'].parts['Part-1']
        session.viewports['Viewport: 1'].setValues(displayedObject=p)
        del mdb.models['Model-1'].sketches['__profile__']

    except:
        import traceback
        print(traceback.format_exc())
```


### 2.forの追加
次に、とりあえずfor文を追加して4回実行してみます。


```Python
    try:
        for i in range(4):
            s1 = mdb.models['Model-1'].ConstrainedSketch(name='__profile__', 
                sheetSize=200.0)
            g, v, d, c = s1.geometry, s1.vertices, s1.dimensions, s1.constraints
            s1.setPrimaryObject(option=STANDALONE)
            s1.rectangle(point1=(0.0, 0.0), point2=(20.0, 5.0))
            session.viewports['Viewport: 1'].view.setValues(nearPlane=180.565, 
                farPlane=196.559, width=46.8405, height=45.3934, cameraPosition=(15.7, 
                -10.547, 188.562), cameraTarget=(15.7, -10.547, 0))
            p = mdb.models['Model-1'].Part(name='Part-1', dimensionality=THREE_D, 
                type=DEFORMABLE_BODY)
            p = mdb.models['Model-1'].parts['Part-1']
            p.BaseSolidExtrude(sketch=s1, depth=20.0)
            s1.unsetPrimaryObject()
            p = mdb.models['Model-1'].parts['Part-1']
            session.viewports['Viewport: 1'].setValues(displayedObject=p)
            del mdb.models['Model-1'].sketches['__profile__']

    except:
        import traceback
        print(traceback.format_exc())
```


すると、1個しかパートは作成されません。

### 3.パート名の変更

そこで、原因はパート名がすべて`Part-1`であることと考え、ループ回数に応じてパート名を変えてみます。
`Part-1`となっているところをすべて`'Part-{}'.format(i)`に置き換えてパート名を変えてみます。
なお、`f'Part-{i}'`とするとエラーになります。これは、`f`がpython3からの機能で、python2にはないからです。

```Python
    try:
        for i in range(4):
            s1 = mdb.models['Model-1'].ConstrainedSketch(name='__profile__', 
                sheetSize=200.0)
            g, v, d, c = s1.geometry, s1.vertices, s1.dimensions, s1.constraints
            s1.setPrimaryObject(option=STANDALONE)
            s1.rectangle(point1=(0.0, 0.0), point2=(20.0, 5.0))
            session.viewports['Viewport: 1'].view.setValues(nearPlane=180.565, 
                farPlane=196.559, width=46.8405, height=45.3934, cameraPosition=(15.7, 
                -10.547, 188.562), cameraTarget=(15.7, -10.547, 0))
            p = mdb.models['Model-1'].Part(name='Part-{}'.format(i), dimensionality=THREE_D, 
                type=DEFORMABLE_BODY)
            p = mdb.models['Model-1'].parts['Part-{}'.format(i)]
            p.BaseSolidExtrude(sketch=s1, depth=20.0)
            s1.unsetPrimaryObject()
            p = mdb.models['Model-1'].parts['Part-{}'.format(i)]
            session.viewports['Viewport: 1'].setValues(displayedObject=p)
            del mdb.models['Model-1'].sketches['__profile__']

    except:
        import traceback
        print(traceback.format_exc())
```



実行すると、無事4つできていることがわかります。


![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/993303/f2b8f894-84b3-1f40-71b0-05e74175d7c3.png)

これで単純作業をマクロ化することができました。
このような形でマクロファイルを編集していきます。



# まとめ

今回は、Abaqusでマクロファイルを使う方法を説明しました。
Abaqusのマクロはトライ安堵エラーをしながら解析していくことになります。
今回はあくまで初歩的な内容にとどまりましたが、将来的にはもう少しいろいろなことも書きたいと思います。