嵌套 openmdao "assemblies"/drivers - 从 0.13 类比工作,这可以在 1.X 中实现吗?
nesting openmdao "assemblies"/drivers - working from a 0.13 analogy, is this possible to implement in 1.X?
我正在使用 NREL 的 DAKOTA_driver openmdao 插件对模型进行并行化 Monte Carlo 采样。在 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) 嵌套问题:您创建了一个包含 DOE driver 的问题 class。您将想要 运行 的案例列表传递给 driver,然后 运行 将它们并行处理。然后你把这个问题作为一个组件放入 parent 问题中。
parent 问题不知道它有一个 sub-problem。它只是认为它有一个使用多个处理器的组件。
这与您在 0.x 中的做法最相似。但是,我不建议走这条路,因为如果您想使用曾经想使用的解析导数,它就不会起作用。
如果你这样使用,dakota driver 几乎可以保持原样。但是你必须使用特殊的 sub-problem class。这还不是官方支持的功能,但它非常可行。
2) 使用 multi-point 方法,您将创建一个代表您的模型的组 class。然后,您将为每个要执行的 monte-carlo 运行 创建该组的一个实例。您将所有这些实例放入整个问题中的平行组中。
这种方法避免了 sub-problem 混乱。它对于实际执行也更有效率。它将比第一种方法稍微大一些 setup-cost。但在我看来,为了获得分析导数的优势而付出一次性的设置成本是非常值得的。唯一的问题是它可能需要对 dakota_driver 的工作方式进行一些更改。您可能希望从 driver 获得一份评估列表,然后将它们分发给各个 children 小组。
我正在使用 NREL 的 DAKOTA_driver openmdao 插件对模型进行并行化 Monte Carlo 采样。在 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) 嵌套问题:您创建了一个包含 DOE driver 的问题 class。您将想要 运行 的案例列表传递给 driver,然后 运行 将它们并行处理。然后你把这个问题作为一个组件放入 parent 问题中。
parent 问题不知道它有一个 sub-problem。它只是认为它有一个使用多个处理器的组件。
这与您在 0.x 中的做法最相似。但是,我不建议走这条路,因为如果您想使用曾经想使用的解析导数,它就不会起作用。
如果你这样使用,dakota driver 几乎可以保持原样。但是你必须使用特殊的 sub-problem class。这还不是官方支持的功能,但它非常可行。
2) 使用 multi-point 方法,您将创建一个代表您的模型的组 class。然后,您将为每个要执行的 monte-carlo 运行 创建该组的一个实例。您将所有这些实例放入整个问题中的平行组中。
这种方法避免了 sub-problem 混乱。它对于实际执行也更有效率。它将比第一种方法稍微大一些 setup-cost。但在我看来,为了获得分析导数的优势而付出一次性的设置成本是非常值得的。唯一的问题是它可能需要对 dakota_driver 的工作方式进行一些更改。您可能希望从 driver 获得一份评估列表,然后将它们分发给各个 children 小组。