嵌套openmdao"组件" /驱动程序 - 从0.13类比工作,这是否可以在1.X中实现?

时间:2016-08-24 16:19:39

标签: optimization openmdao robustness

我正在使用NREL的DAKOTA_driver openmdao插件进行模型的并行蒙特卡罗采样。在0.X中,我能够嵌套程序集,允许外部优化驱动程序指示DAKOTA_driver抽样评估。我可以将此设置嵌套在外部优化器中吗?我希望外部优化器的工作流程能够调用DAKOTA_driver" assembly"然后是get_dakota_output组件。

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 个答案:

答案 0 :(得分:1)

这种情况有两种不同的选择。两者都将并行工作,目前都可以支持。但是当你想使用分析衍生物时,其中只有一个会起作用:

1)嵌套问题:您创建了一个具有DOE驱动程序的问题类。您将要运行的案例列表传递给该驱动程序,并且它们并行运行它们。然后,您将该问题作为组件放入父问题中。

父问题不知道它有子问题。它只是认为它有一个使用多个处理器的组件。

这与你在0.x中完成它的方式最相似。但是我建议不要使用这条路线,因为如果你想使用分析衍生物就无法使用它。

如果你使用这种方式,dakota驱动程序可以保持原样。但是你必须使用一个特殊的子问题类。这不是官方支持的功能,但它非常可行。

2)使用多点方法,您将创建一个表示模型的Group类。然后,您将为要执行的每个monte-carlo运行创建该组的一个实例。您将所有这些实例放入整个问题中的并行组中。

这种方法避免了子问题的混乱。它对于实际执行也更有效。它将比第一种方法具有更高的设置成本。但在我看来,为了获得分析衍生产品的优势,一次性设置成本非常值得。唯一的问题是它可能需要对dakota_driver的工作方式进行一些更改。您可能希望从驱动程序获取评估列表,然后将它们交给各个子组。