FreeCADで構造最適化

# 構造最適化

ちょっとした経緯からTopology Optimizationが面白そうだったので、FreeCADで試してみました
当初自分の勉強用に始めたので、前半と後半で少し形状が異なるかもしれません。
ご容赦ください。

ゆがみはほぼ変わらず、体積をおおよそ半部とする形状を出力することができました


 モデル | Z方向最大変位 | 体積 |
|:-:|:-:|:-:|
| 最適化前  | -12.57㎛  | 11534 |
| 最適化後| -17.49㎛  | 5816  |


# 最適化する前の形状を作成する

今回は、棚を支える三角形部分の形状最適化をすることにします。
以下は出来上がった形状をBlenderでレンダリングしたイメージ図です。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/121950/0e91d1ca-9baf-c8ba-9a4f-8a02a26a30b2.png)

# BESOスクリプトのダウンロード

FreeCADには標準ではToplogy最適化の機能はありません。調べたところ、以下のBESOスクリプトを用いるとできるようです。インストールは特にないのですが、FreeCADのアドオンディレクトリに展開してもよいと思います。

https://github.com/calculix/beso

# 形状作成

まずは削る前の形状を設計します。この辺りはFreeCADの基本なのでかなりはしょります。

スケッチから、XZ平面を選択します。実際のところどの平面でも特に問題ないはずです。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/121950/d53636ab-8bc5-e83b-e4a0-4578f6a4c350.png)

５㎝の直角三角形を作成します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/121950/06dcb791-3c5c-1587-53e9-0acad9a7a21a.png)

Padで２㎝の厚みを出します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/121950/3c455105-18bd-835b-826f-fe6f69bd48fa.png)

# FEM開始

ワークベンチをFEMへ切り替えます。
開くと、デフォルトのSolverだけがセットされています。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/121950/bfe22eef-0484-6026-c3e7-296ad07d9e6b.png)

## 素材設定
”A”のマークをクリックすると解析コンテナーが追加されます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/121950/8742b6ac-04cd-4307-edc8-df06dc77af19.png)

次にこの形状を構成する素材を設定します。
鉄とプラスチックでは当然強さや変形の仕方が違いますからね。

”A”のマークの隣の黄色い球をクリックします。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/121950/a746ce30-ba66-48cf-ae30-d9726cf8f81b.png)

追加されたMaterialSolidをダブルクリックして設定を開きます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/121950/5c135cc4-bcf6-4a7f-b0c4-12938814a5b1.png)


FEM材料が表示されるので、情報の▽をクリックして、適当な素材を選びます。
ここでは３Dプリンタでも用いられるABSを選びます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/121950/9f10e89c-771a-4ae5-a57e-13cf13360110.png)

## 固定境界条件
今回棚の支えを設計すると想像すると、一面は壁に固定され、上面から荷重がかかりますね。
ここでは壁に固定する面の設定を行います。

これを固定境界上限の設定と呼ぶらしいです。
画面上部に鍵のマークがついたアイコンをクリックします。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/121950/5e4912c8-06cd-4245-a0e0-7463b451fec5.png)

タスクに設定が表示されるので、「追加」ボタンをクリックしてから固定する面を選択します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/121950/20f53d6b-f799-4ae2-bf6a-5981dbd63e7c.png)

選択した面に赤マークが出ることを確認してOKをクリック。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/121950/5eb9f989-1581-46d5-a882-94fa46496acd.png)

## 荷重負荷

後は荷物が上面に置かれたら、面全体に荷重がかかると想定します。
理想的にはたわみなどがなければそうなるはずですよね。

アイコンで荷重負荷をクリックします。面に赤い矢印のアイコンです。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/121950/b90bc1cf-a8e3-4153-8569-79d2b4d2f8e8.png)


固定境界条件と同じように、圧力がかかる面を選択してOKをクリック。
私の環境では矢印の方向が面への方向ではなく逆方向だったので、設定にある「逆方向」にチェックをいれいました。
10㎏のものを2つの足で支えると想定し、荷重は49.00Nとしました。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/121950/8d1699f3-0a5f-49e9-b112-8996daab556f.png)

## Mesh

FEMメッシュを生成します。
まずはBodyを選択します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/121950/9ea6f4c5-69fa-451e-8a29-980bfe49fa44.png)

すると、FEMメッシュ作成のボタンが有効化されるので、今回はNが付いているNetGenをもちいてFEMMeshを生成します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/121950/0ceaa8d6-7252-4436-ba40-ffe3f0ff6c44.png)

例によってパラメータがタスクに表示されます。
デフォルトでは分割が大きすぎるので、最大サイズを2㎜とします。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/121950/ff3b82aa-2d87-4d59-bd2e-270ff219a569.png)

OKをクリックすると、AnalysisのしたにFEMMeshNetgenが追加されます。
これくらいのおおざっぱさでも1.9万のNodeが構成されたようです。体積が11534。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/121950/b87ac725-6acb-45f7-bdf4-191d98b7e562.png)

## ソルバー計算の実行

モデルのなかから、「SolverCcxTools」を選択する。Ｓに実行の矢印が付いたアイコン。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/121950/8402c3e6-63f9-48af-8581-6f6dad3d5595.png)

Solverの実行アイコンが有効になるので、クリックする。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/121950/585f22e0-e399-4d61-a4b3-b6c0a756b293.png)

するとAnalysisのしたに3つくらい項目が増える。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/121950/93555f9d-ede6-458b-bc66-213b9fad781d.png)

## 結果確認
CCX‗Resultをダブルクリックする。

画面上のこうもくで、
「変位Z」を選択。
変位のチェックボックスをクリックしてスライドバーを意味版右までもっていくとゆがみが分かるように表示される。
＊どれくらい歪むかの値は、上記にこの例では最大12.57㎛とあるので非常に小さい。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/121950/f429f1ab-514a-4e66-aafa-48944c87465f.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/121950/b0ccd66f-7024-44e3-9570-96985650f2e7.png)

#構造最適化

ここまでが準備でここからが本番。

## Inpファイルの書き出し
「SolverCczxTools」をダブルクリックするとInpファイルの書き出しが可能となる。
念のため、日本語を含まないパスを設定して、「.Inpファイルの書き出し」をクリック。途中計算が大量に出力されるので、専用のフォルダを作成し、書き出しを行う方が良いです。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/121950/35a17f11-fbad-46fe-bc91-24329258b659.png)

## BESOマクロ実行
メニューのマクロからさらにその下にある「マクロ」を選択する。

マクロの実行画面がひょうじされるので、「ユーザーマクロの保存先」に、BESOを展開したフォルダを設定する。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/121950/ebaf38b2-4a39-4644-8fee-919ed6bb5289.png)

一覧の中から「beso_fc_gui.py」を選択し、実行をクリックする。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/121950/c7de30fe-3951-43d1-a5c9-f54364ece07b.png)

左上の「Select analysis file」ボタンをクリックして、先ほど書き出した.Inpを選択。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/121950/85831333-aa7e-44ba-a61c-d42f48a9a91f.png)

「Mass goal ratio」を0.5として、目標を50％の質量とします。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/121950/364a33b7-fc44-4790-a03f-d09866da5738.png)


あとはデカい「Generate conf. file and run optimization」ボタンをクリックします。
反応がなくわかりにくいですが、しばらくするとグラフが出ます。
重なって出たりするので、よく見ておきましょう…
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/121950/35bae1ce-a290-4c92-bda3-43f343ebcb75.png)

表示されたグラフが更新されるのと、(表示していれば)ログも更新されます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/121950/78c704d9-2170-4129-b6ee-dad47b0a15f6.png)

ある程度まで行くと変化がなくなりますが、止まるまで待ちます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/121950/59701aa7-4bb8-4b4f-b661-a539288fd326.png)

止まったら、グラフおよびマクロのウィンドウは×で閉じても構いません。


# 最適化結果確認
さて、BESOで作られた形状はどのような形でしょう。

## 形状確認
マクロが終了すると、フォルダに大量のファイルが作成され終了します。
ループごとに削減された形状、残った形状などの情報がのこされます。例えば、file020_state1.inpはループ20回目の残っている形状になります。

停止したフォルダの時系列で以後の_state1.inpをFreeCADへD＆Dします。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/121950/4ea44932-223a-46c5-9513-4cc566d0d5a5.png)

## 再度変形を確認する。
SolverCcxToolsを選択し、Solver計算の実行を実行します。
結果がこちら。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/121950/49c59648-65a0-4358-8c7b-bcf5023a5f2e.png)

| モデル | Z方向最大変位 | 体積 |
|:-:|:-:|:-:|
| 最適化前  | -12.57㎛  | 11534 |
| 最適化後| -17.49㎛  | 5816  |