在 openmdao 1.x 中,这种过程还没有通过 DOE 直接支持,但它绝对是可能的。您可以采取两种途径,根据您的最终目标提供不同的好处。
我将根据一个高级分类来区分不同的场景:
1)您想围绕整个 DOE/元模型组合进行基于梯度的优化。例如,如果您想使用 CFD 预测几个关键点的阻力,然后使用元模型生成用于任务分析的阻力极坐标,就会出现这种情况。这种建模的一个很好的例子可以在这篇关于同时飞机任务设计优化的论文中找到。.
2)您不想围绕整个模型进行基于梯度的优化。您可能想要进行无梯度优化(如遗传算法)。您可能希望仅围绕代理本身进行基于梯度的优化,并使用固定的训练数据。或者您可能根本不想进行优化...
如果您的用例属于场景 1(或将来最终属于此用例),那么您希望使用多点方法。您为每个训练案例创建一个模型实例,然后您可以将结果混合到一个数组中,然后传递给元模型。这是必要的,以便可以通过完整模型传播导数。多点方法会很好地工作,并且非常可并行化。根据您将用于生成训练数据本身的模型结构,您还可以考虑使用分布式组件的稍微不同的多点方法或一系列链接在一起的分布式组件。如果您的模型支持它,分布式组件方法是在这种情况下使用的最有效的模型结构。
如果您的用例属于场景 2,您仍然可以根据需要使用多点方法。它将开箱即用。但是,您也可以考虑使用常规 DOE 来生成训练数据。为此,您需要使用嵌套问题方法,将 DOE 训练数据生成放在子问题中。这也将起作用,尽管您需要进行一些额外的编码才能从 DOE 中获取结果数组,因为目前尚未实现。
如果您想使用 DOE 生成数据,然后将其传递到下游的代理,以进行优化,您可以使用一对问题实例。这并不一定需要您提出嵌套问题。相反,您只需构建一个运行脚本,该脚本具有一个使用 DOE 的问题实例,完成后您将数据收集到一个数组中。然后,您可以在第二个问题实例中手动将其分配给元模型的训练输入。类似于以下伪代码:
prob1 = Problem()
prob1.driver = DOE()
#set up the DOE variables and model ...
prob1.run()
training_data = prob1.driver.results
prob2 = Problem()
prob2.driver = Optimizer()
#set up the meta-model and optimization problem
prob2['meta_model.train:x'] = training_data
prob2.run()