OpenMDAOではじめる最適化 (4/4)

スクリプトからの操作例

2014/12/3

バージョン0.9.5

OpenMDAOはGUIからだけでなくPythonから使用することができる。

Pythonで作成したコンポーネントやドライバーを組み合わせて作成したアセンブリをGUIに読み込んで使用することもできるので最適化プロセスの作成はPython、パラメター変更・最適化実行はGUIという風に使い分けることも可能。

コンポーネントの作成

まずコンポーネントを作成する。Paraboloid.py というファイル名でテキストファイルを作成し以下の内容を書き込む。

from openmdao.main.api import Component
from openmdao.lib.datatypes.api import Float

class Paraboloid(Component):
        """ f(x,y) = (x-3)^2 + xy + (y+4)^2 - 3 """
        # set up interface to the framework
        x = Float(0.0, iotype='in', desc='The variable x')
        y = Float(0.0, iotype='in', desc='The variable y')
        f_xy = Float(0.0, iotype='out', desc='F(x,y)')
       
        def execute(self):
                """f(x,y) = (x-3)^2 + xy + (y+4)^2 - 3
                Minimum : x = 6.6667; y = -7.3333
                """
                x = self.x
                y = self.y
                self.f_xy = (x-3.0)**2 + x*y + (y+4.0)**2 - 3.0

解説

  1. コンポーネントを作成するので必ず Component クラスをインポートする
    from openmdao.main.api import Component
  2. Component を継承した Python のクラスとして自作コンポーネントを定義する
    class Paraboloid(Component):
  3. コンポーネントへの入力値は iotype='in' とする
    x = Float(0.0, iotype='in', desc='The variable x')
    y = Float(0.0, iotype='in', desc='The variable y')
  4. コンポーネントからの出力値は iotype='out' とする
    f_xy = Float(0.0, iotype='out', desc='F(x,y)')
  5. メソッド名 execute のメソッドを必ず作成する。このメソッドが OpenMDAO によって自動実行される。
    def execute(self):
  6. 入力から出力を求める。流体解析や構造解析のソルバーを使う場合はここに組み込んで使用する。
    x = self.x
    y = self.y
    self.f_xy = (x-3.0)**2 + x*y + (y+4.0)**2 - 3.0

アセンブリの作成

次にアセンブリを作成してワークフローを定義する。OptimizationUnconstrained.py というファイル名でテキストファイルを作成し以下の内容を 書き込む。

from openmdao.main.api import Assembly
from openmdao.lib.drivers.api import SLSQPdriver
from openmdao.examples.simple.paraboloid import Paraboloid

class OptimizationUnconstrained(Assembly):
        """Unconstrained optimization of the Paraboloid Component."""

        def configure(self):

                # Create Optimizer instance
                self.add('driver', SLSQPdriver())

                # Create Paraboloid component instances
                self.add('MyParaboloid', Paraboloid())

                # Iteration Hierarchy
                self.driver.workflow.add('MyParaboloid')

                # SLSQP Flags
                self.driver.iprint = 0

                # Objective
                self.driver.add_objective('MyParaboloid.f_xy')

                # Design Variables
                self.driver.add_parameter('MyParaboloid.x', low=-50., high=50.)
                self.driver.add_parameter('MyParaboloid.y', low=-50., high=50.)

                # Initialize Targets
                self.MyParaboloid.x = 10
                self.MyParaboloid.y = 10

解説

  1. アセンブリを作成するので必ず Assembly クラスをインポートする
    from openmdao.main.api import Assembly
  2. Assemblyを継承したPythonのクラスとして自作アセンブリを定義する
    class OptimizationUnconstrained(Assembly):
  3. アセンブリの組み立ては configure メソッドでおこなう
    def configure(self):
  4. 名前を「driver」としてドライバーをアセンブリに追加
    self.add('driver', SLSQPdriver())
  5. 名前を「MyParaboloid」としてコンポーネントをアセンブリに追加
    self.add('MyParaboloid', Paraboloid())
  6. ドライバーとコンポーネントを関連付け
    self.driver.workflow.add('MyParaboloid')
  7. ログ出力設定
    self.driver.iprint = 0
  8. 目的関数の設定
    self.driver.add_objective('MyParaboloid.f_xy')
  9. 範囲を指定して設計変数を設定
    self.driver.add_parameter('MyParaboloid.x', low=-50., high=50.)
    self.driver.add_parameter('MyParaboloid.y', low=-50., high=50.)
  10. 設計変数の初期値を設定
    self.MyParaboloid.x = 10
    self.MyParaboloid.y = 10

実行用コード

下記実行用コードをアセンブリの定義されているスクリプト(OptimizationUnconstrained.py)の末尾に書く
if __name__ == "__main__":
        opt_problem = OptimizationUnconstrained()
        import time
        tt = time.time()
        opt_problem.run()
        print "\n"
        print "Minimum found at (%f, %f)" % (opt_problem.MyParaboloid.x, opt_problem.MyParaboloid.y)
        print "Elapsed time: ", time.time()-tt, "seconds"

解説

  1. 自作アセンブリをインスタンス化
    opt_problem = OptimizationUnconstrained()
  2. 計算実行
    opt_problem.run()
  3. 「(アセンブリのインスタンス名).(コンポーネントのインスタンス名).(変数名)」で値を参照することが可能なのでそれを使って最適化の結果を取得する
    print "Minimum found at (%f, %f)" % (opt_problem.MyParaboloid.x, opt_problem.MyParaboloid.y)

計算の実行と結果確認

以上で次の2ファイルが作成できた。 この2ファイルを同じフォルダに置き、PythonからOptimizationUnconstrained.pyを実行する。
C:\OpenMDAO\openmdao-0.9.5>Scripts\activate
(openmdao-0.9.5) C:\OpenMDAO\openmdao-0.9.5>python D:\Workspace\OptimizationUnconstrained.py

Minimum found at (6.666666, -7.333334)
Elapsed time: 0.018000125885 seconds

最適化がおこなわれ、「f(x, y) = (x-3)2 + xy + (y+4)2– 3」が最小となる (x、 y) は (6.666666, -7.333334) であることが得られる。

GUIへの読み込み

作成したPythonスクリプトをGUI上で読み込むことでパラメータ設定や最適化の実行をGUI上でおこなうことも可能。スクリプトは次のようにして読み込むことができる。
  1. ウィンドウ左側の「Files」タブの「Add Files」をクリックして「OptimizationUnconstrained.py」を読み込む
    LoadingAssembly1
  2. ウィンドウ右側の「Library」タブに「OptimizationUnconstrained」が追加されるのでキャンバスにドラッグ&ドロップ
    LoadingAssembly2
  3. ダイアログでOptimizationUnconstrainedのインスタンスに適当な名前をつけてOKをクリック
    LoadingAssembly3
  4. スクリプトで作成したアセンブリがGUI上に読み込まれるので後は「GUIからの操作例」と同様に最適化を実行する。パラメータの変更などの操作もGUIから可能。
    LoadingAssembly4

まとめ

参照

目次 1 2 3 4