2016-08-24 1 views
0

モデルの並列モンテカルロサンプリングにNRELのDAKOTA_driver openmdaoプラグインを使用しています。 0.Xでは、アセンブリをネストすることができ、外部最適化ドライバがDAKOTA_driverサンプリング評価を指示することができました。外部オプティマイザでこの設定をネストすることは可能ですか?外部オプティマイザのワークフローで、DAKOTAドライバのget_dakota_outputコンポーネントを呼び出すようにしたいと思います。openmdao "assemblies"/driversを入れ子にしました - 0.13の類推から作業していますが、これは1.Xで実装することが可能ですか?

import pandas as pd 
import subprocess 
from subprocess import call 
import os 
import numpy as np 
from dakota_driver.driver import pydakdriver 
from openmdao.api import IndepVarComp, Component, Problem, Group 

from mpi4py import MPI 
import sys 
from itertools import takewhile 
sigm = .005 
n_samps = 20 
X_bar=[0.065 , sigm] #2.505463e+03*.05] 
dacout = 'dak.sout' 


class get_dak_output(Component): 
    mean_coe = 0 

    def execute(self): 
     comm = MPI.COMM_WORLD 
     rank = comm.Get_rank() 
     nam ='ape.net_aep' 
     csize = 10000 
     with open(dacout) as f: 
      for i,l in enumerate(f): 
       pass 
     numlines = i 
     dakchunks = pd.read_csv(dacout, skiprows=0, chunksize = csize, sep='there_are_no_seperators') 
     linespassed = 0 
     vals = [] 
     for dchunk in dakchunks: 
      for line in dchunk.values: 
       linespassed += 1 
       if linespassed < 49 or linespassed > numlines - 50: continue 
       else: 
        split_line = ''.join(str(s) for s in line).split() 
       if len(split_line)==2: 
        if (len(split_line) != 2 or 
         split_line[0] in ('nan', '-nan') or 
         split_line[1] != nam): 
          continue 
        else:vals.append(float(split_line[0])) 
     self.coe_vals = sorted(vals) 
     self.mean_coe = np.mean(self.coe_vals) 


class ape(Component): 
    def __init__(self): 
     super(ape, self).__init__() 
     self.add_param('x', val=0.0) 
     self.add_output('net_aep', val=0.0) 

    def solve_nonlinear(self, params, unknowns, resids): 
     print 'hello' 
     x = params['x'] 
     comm = MPI.COMM_WORLD 
     rank = comm.Get_rank() 
     outp = subprocess.check_output("python test/exampleCall.py %f"%(float(x)), 
     shell=True) 

     unknowns['net_aep'] = float(outp.split()[-1]) 


top = Problem() 

root = top.root = Group() 

root.add('ape', ape()) 
root.add('p1', IndepVarComp('x', 13.0)) 
root.connect('p1.x', 'ape.x') 

drives = pydakdriver(name = 'top.driver') 
drives.UQ('sampling', use_seed=False) 
#drives.UQ() 
top.driver = drives 
#top.driver = ScipyOptimizer() 
#top.driver.options['optimizer'] = 'SLSQP' 

top.driver.add_special_distribution('p1.x','normal', mean=0.065, std_dev=0.01, lower_bounds=-50, upper_bounds=50) 
top.driver.samples = n_samps 
top.driver.stdout = dacout 
#top.driver.add_desvar('p2.y', lower=-50, upper=50) 
#top.driver.add_objective('ape.f_xy') 
top.driver.add_objective('ape.net_aep') 

top.setup() 


top.run() 
bak = get_dak_output() 
bak.execute() 

print('\n') 
print('E(aep) is %f'%bak.mean_coe) 
+1

コードサンプルがちょっと変わっています。それにはopenmdao 1.xとopenmdao 0.xの両方のコンポーネントがあります。それは目的ですか? –

+0

これはopenmdao 1.Xで動作します...いいえ、それは意図的なものではありません - あなたが参照しているコードのどの部分が好奇妙なのですか?私は0.Xから変換しています。私はコメント0.Xコードを削除する質問を編集しました。 – kilojoules

答えて

1

この状況には2つの異なるオプションがあります。両方とも並行して動作し、どちらも現在サポートされています。ただし、解析的な派生物を使用する場合は、そのうちの1つのみが機能します。

1)ネストされた問題:DOEドライバを含む問題クラスを1つ作成します。そのドライバに実行したいケースのリストを渡し、それらを並列に実行します。次に、その問題を親の問題にコンポーネントとして入れます。

親の問題は、それに副問題があることを知らない。それは、それが複数のプロセッサを使用する単一のコンポーネントを持っていると考えているだけです。

これは、0.xで行ったのと同じ方法です。しかし、私はこのルートを進めることをお勧めしません。なぜなら、分析的な派生物を使いたいと思っているなら、それはうまくいかないからです。

この方法を使用すると、dakotaドライバはそのままの状態を維持できます。しかし、特殊なサブ問題クラスを使用する必要があります。これはまだ正式にサポートされている機能ではありませんが、非常に有効です。

2)マルチポイントアプローチを使用すると、モデルを表すGroupクラスを作成できます。次に、実行するモンテカルロの実行ごとにそのグループのインスタンスを1つ作成します。全体の問題の中で、これらのインスタンスをすべて並列グループに入れます。

このアプローチは、サブ問題の混乱を回避します。実際の実行にはずっと効率的です。最初の方法よりも設定コストがいくらか大きくなります。しかし、私の意見では、その有益なのは、分析的な派生物の利点を得るために一度のセットアップコストです。唯一の問題は、おそらくdakota_driverの動作にいくつかの変更が必要になることです。あなたはドライバーから評価のリストを取得し、それを個々の子グループに渡したいと思うでしょう。

+0

少し接する質問:OpenMDAOのDOEドライバが回答を集めることができますか? DOEチュートリアルでは、応答の一覧(および関連するグラデーション情報)がアクセス可能になることを期待していました。 https://openmdao.readthedocs.io/en/latest/usr-guide/tutorials/doe-drivers.html – kilojoules

+0

実装するのは難しくありませんが、ドライバを変更する必要があります。特にグラデーション情報が必要な場合は特に。現在、DOEドライバは、導関数を計算しません。一般的に言えば、これは実際には効率的ではないでしょう。なぜなら、関数呼び出しを行うたびに派生したくないからです。ライン検索や信頼領域メソッドは、派生を必要とせずに評価されることがよくあります。 –

+0

意味があります。 「堅牢な最適化」ドライバを探索することは興味深いでしょう。 – kilojoules

関連する問題