我是OpenMDAO的新手,我还在学习如何制定问题。 举一个简单的例子,假设我有3个具有给定边界的输入变量:
1 <= x <= 10
0 <= y <= 10
1 <= z <= 10
我有4个输出,定义为:
f1 = x * y
f2 = 2 * z
g1 = x + y - 1
g2 = z
我的目标是最小化f1 * g1,但强制执行约束f1 = f2和g1 = g2。例如,一个解是x = 3,y = 4,z = 6(不知道这是否是最优的)。
对于这个简单的问题,您可能只是将输出相等约束提供给驱动程序。但是,对于我的实际问题,很难找到满足所有约束的初始起点,因此优化器无法执行任何操作。我想也许我可以将y和z定义为隐式组件中的状态,并让非线性求解器计算出给定x的y和z的正确值,然后将x提供给优化驱动程序。
这是一种可行的方法吗?如果是这样,在这种情况下隐式组件将如何?我查看了Sellar问题教程,但我无法将其翻译成这种情况。
答案 0 :(得分:1)
如果需要,您可以创建隐式组件。在这种情况下,您将在组件中定义apply_linear
方法。这是通过sellar问题here完成的。
在你的情况下,由于你有两个方程组的残差都依赖于状态变量,我建议你创建一个长度为2的单个数组状态变量,称之为foo
(我使用了一个新的变量避免任何混淆,但任何你想要的名称!)。然后,您将定义两个残差,一个用于新状态变量的剩余数组的每个元素。
类似的东西:
resids['foo'][0] = params['x'] * unknowns['foo'][0] - 2 * unknowns['foo'][1]
resids['foo'][1] = params['x'] + unknowns['foo'][0] - 1 - unknowns['foo'][1]
如果您希望将状态变量名称保持独立,那么它仍然有效。您只需要将一个残差方程任意分配给一个变量,将一个残差方程分配给另一个变量。
然后唯一剩下的就是将一个非线性求解器添加到包含隐式组件的组中,它应该可以工作。如果您选择使用牛顿求解器,则需要设置fd_options['force_fd'] = True
或定义残差的导数以及所有参数和状态变量。