設計変数の拘束式

この例では、パラメータの組み合わせを制限する場合に拘束関数を使用する方法について説明します。

サンプルファイル

注釈

サンプルプロジェクト を Femtet で開いたまま、 サンプルコード をダブルクリックして実行してください。

設計変数と解析条件

../../_images/model1.png

解析モデルの概要と設計変数

変数名

説明

external_r

管の外径

internal_r

管の内径

目的関数

ミーゼス応力の最大値

サンプルコード

constrained_pipe.py
 1"""拘束付き最適化を実装するサンプル。
 2
 3このセクションでは、拘束の種類と、拘束を必要とするモデルで
 4最適化を実行する手順について説明します。
 5
 6"""
 7
 8from pyfemtet.opt import FEMOpt, OptunaOptimizer
 9from pyfemtet.opt.optimizer import PoFBoTorchSampler
10
11
12def mises_stress(Femtet):
13    """フォンミーゼス応力を目的関数として計算します。
14
15    この関数は、最適化の実行中に FEMOpt オブジェクトによって
16    自動的に呼び出されます。
17
18    引数:
19        Femtet: PyFemtet を使用して目的関数または拘束関数を
20            定義する場合、最初の引数は Femtet インスタンスを
21            取る必要があります。
22
23    戻り値:
24        float: 目的または拘束関数は単一の float を返すよう定義してください。
25    """
26    return Femtet.Gogh.Galileo.GetMaxStress_py()[2]
27
28
29def radius_diff(Femtet, opt):
30    """パイプの外側の半径と内側の半径の差を計算します。
31
32    この拘束は、最適化の実行中にパイプの内側の半径が
33    外側の半径を超えないようにするために呼び出されます。
34
35    注意:
36        OptunaOptimizer の BoTorchSampler を使用していて、
37        strict な拘束を使用する場合、パラメータを提案するため
38        に繰り返し計算が必要になるため、Femtet へのアクセスが
39        非常に遅くなる可能性があることに注意してください。
40        この関数の例のように、Femtet にアクセスするのではなく、
41        Optimizer オブジェクトを介してパラメータを取得して計算
42        を実行することをお勧めします。
43
44        非推奨::
45
46            p = Femtet.GetVariableValue('p')
47
48        代わりに::
49
50            params = opt.get_parameter()
51            p = params['p']
52
53    引数:
54        Femtet: PyFemtet を使用して目的関数または拘束関数を
55            定義する場合、最初の引数は Femtet インスタンスを
56            取る必要があります。
57        opt: このオブジェクトを使用すると、Femtet を経由せず
58            に外側の半径と内側の半径の値を取得できます。
59    """
60    params = opt.get_parameter()
61    internal_r = params['internal_r']
62    external_r = params['external_r']
63    return external_r - internal_r
64
65
66if __name__ == '__main__':
67    # 最適化手法のセットアップ
68    opt = OptunaOptimizer(
69        sampler_class=PoFBoTorchSampler,
70        sampler_kwargs=dict(
71            n_startup_trials=3,  # 最初の 3 回はランダムサンプリングを行います。
72        )
73    )
74    femopt = FEMOpt(opt=opt)
75
76    # 変数の追加
77    femopt.add_parameter("external_r", 10, lower_bound=0.1, upper_bound=10)
78    femopt.add_parameter("internal_r", 5, lower_bound=0.1, upper_bound=10)
79
80    # 最適化の実行中に外側の半径を超えないように strict 拘束を追加します。
81    femopt.add_constraint(
82        fun=radius_diff,  # 拘束関数 (ここでは 外半径 - 内半径).
83        name='管厚さ',  # 拘束関数にはプログラム上の名前とは別に自由な名前を付与できます.
84        lower_bound=1,  # 拘束関数の下限 (ここでは管の厚みを最低 1 とする).
85        args=(femopt.opt,)  # 拘束関数に渡される、Femtet 以外の追加の引数.
86    )
87
88    # 目的関数の追加
89    femopt.add_objective(fun=mises_stress, name='ミーゼス応力')
90
91    # 最適化の実行
92    femopt.set_random_seed(42)
93    femopt.optimize(n_trials=10)

サンプルコードの実行結果

../../_images/result1.png

constrained_pipe.py の実行結果です。wall thickness が 1 未満である試行は存在しません。

注釈

Femtet, PyFemtet および依存する最適化エンジンのバージョンにより、結果は多少異なる場合があります。