问题描述
Ax = b
其中 A 和 b 是已知状态和源自早期组件的状态速率的混合,x 是四个未知状态速率的向量。我已经使用 Matlab 将问题线性化,我现在需要做的就是创建一些组件来查找 x。但是,就每个索引中的变量数量而言,A 的倒数很大,因此我不能将它们变成一个简单的线性方程。有人可以建议路线吗?
解决方法
我不完全理解您所说的“就每个索引中的变量数量而言 A 的倒数很大”是什么意思,但是我认为 A 的倒数的意思是计算和存储更大且更密集记忆中。
OpenMDAO 与否,当您遇到这种情况时,您将不得不使用诸如 gmres 之类的迭代线性求解器。所以这也是这里所需要的方法。
OpenMDAO 确实有一个 LinearSystemComponent,您可以在此处将其用作粗略的蓝图。但是,它确实计算了分解并存储了它,这不是您想要的。无论如何,它为您提供了如何在 OpenMDAO 中将线性系统表示为 implicit component 的蓝图。
从广义上讲,您必须考虑定义线性残差: R = Ax-b = 0
您的组件将有两个输入 A
和 b
,以及一个输出 x
。
这里的两个关键方法是 apply_nonlinear
和 solve_nonlinear
。我意识到方法名称中的单词 nonlinear
令人困惑。 OpenMDAO 假设分析是非线性的。在您的情况下,它恰好是线性的,但您使用的 nonlinear
方法完全相同。
我会假设,虽然您不能计算/存储 [A] 逆,但您可以计算/存储 A(可能采用稀疏格式)。在这种情况下,您可以将 [A] 的稀疏数据数组作为输入传递,并根据需要从中填充稀疏矩阵。
apply_nonlinear
方法如下所示:
def apply_nonlinear(self,inputs,outputs,residuals):
"""
R = Ax - b.
Parameters
----------
inputs : Vector
unscaled,dimensional input variables read via inputs[key]
outputs : Vector
unscaled,dimensional output variables read via outputs[key]
residuals : Vector
unscaled,dimensional residuals written to via residuals[key]
"""
residuals['x'] = inputs['A'].dot(outputs['x']) - inputs['b']
您问题的关键实际上是solve_nonlinear method
。它看起来像这样 (using scipy gmres):
def solve_nonlinear(self,outputs):
"""
Use numpy to solve Ax=b for x.
Parameters
----------
inputs : Vector
unscaled,dimensional output variables read via outputs[key]
"""
x,exitCode = gmres(inputs['A'],inputs['b'])
outputs['x'] = x