【问题标题】:Error when computing jacobian vector product计算雅可比向量积时出错
【发布时间】:2020-04-13 14:39:35
【问题描述】:

我有一个具有耦合学科的组,该组嵌套在所有其他组件都未耦合的模型中。我已经为耦合组分配了一个非线性牛顿和线性直接求解器。

当我尝试使用默认的“RunOnce”求解器运行模型时,一切正常,但一旦我尝试运行优化,我就会收到以下来自 linear_block_gs.py 的错误:

文件“...\openmdao\core\group.py”,第 1790 行,在 _apply_linear scope_out, scope_in)
文件“...\openmdao\core\explicitcomponent.py”,第 339 行,在 _apply_linear self.compute_jacvec_product(*args)
文件“...\Thermal_Cycle.py”,第 51 行,compute_jacvec_product d_inputs['T'] = 斜率 * deff_dT / alp_sc setitem 中的文件“...\openmdao\vectors\vector.py”,第 363 行 raise KeyError(msg.format(name)) KeyError: '未找到变量名“T”。'

下面是模型的N2图。错误中提到的变量“T”来自隐含的“temp”组件,并反馈给“sc”组件(错误消息中的文件Thermal_Cycle.py)作为输入。

N2 diagram

当我在整个模型之上分配 DirectSolver 时,错误消失了。我的印象是,只要具有隐式组件的组按照 here 的建议应用了适当的求解器,并且在我的情况下已完成,“RunOnce”就可以工作。为什么在尝试计算模型的总导数时不起作用,即为什么compute_jacvec_product找不到耦合变量“T”?

我想使用“RunOnce”求解器的原因是,当我的变量向量“T”增加时,使用 DirecSolver 进行优化会变得很长。我怀疑使用线性“RunOnce”应该更快?

【问题讨论】:

    标签: openmdao


    【解决方案1】:

    我认为compute_jacvec_product 方法的这个示例可能会有所帮助。

    问题在于,根据求解器配置或模型结构,OpenMDAO 可能只需要您在此方法中提供的部分部分。例如,您的无矩阵组件可能有两个输入,但只有一个连接,因此 OpenMDAO 不需要关于未连接输入的导数,事实上,它不会在 d_inputs 或 d_outputs 向量中为其分配空间。

    因此,要解决此问题,您只需在分配值之前添加一个 if 语句,就像在示例中一样。

    【讨论】:

      【解决方案2】:

      基于 N2,我认为我同意您将直接求解器仅围绕耦合放置的策略。这应该可以正常工作,但是看起来您正在组件中实现线性运算符,基于:

      File "...\Thermal_Cycle.py", line 51, in compute_jacvec_product d_inputs['T'] = slope * deff_dT / alp_sc 
      

      您不应该使用带有无矩阵部分的直接求解器。直接求解器计算逆矩阵,这需要矩阵的完整组装。它起作用的唯一原因是 OM 具有一些后备功能,可以通过 compute_jacvec_product 方法传递单位矩阵的列来手动组装 jacobian。 这种回退机制可以让事情正常进行,但它非常慢(你最终会打电话给compute_jacvec_product A LOT)。

      您遇到的错误,以及当您将直接求解器置于模型中较高位置时它为何起作用的原因,可能是由于您的 compute_jacvec_product 实现中缺少必要的 if 条件。 请参阅docs on explicit component for some examples,但关键的见解是要意识到在进行 jacvec 乘积时并非每个变量都会出现(这取决于正在完成的求解类型 --- 即一个用于牛顿,一个用于总导数整个模型)。 因此,需要这些 if 检查来检查变量是否相关。这样做是因为对于昂贵的代码(即 CFD),其中一些操作非常昂贵,除非您需要,否则您不想执行它们。

      您的组件是否太大以至于无法使用compute_partials 功能?你试过specifying the sparsity in your jacobian吗?通常,在您开始使用具有 1e6 或更多隐式输出变量的真正大型 PDE 求解器之前,不需要矩阵无偏导数方法。

      没有看到一些代码,很难更详细地评论,但总结一下: 您不应将compute_jacvec_product 与直接求解器结合使用。如果您真的需要无矩阵的部分,那么您需要切换到迭代线性求解器 liket PetscKrylov

      如果您可以在Thermal_Cycle.py 中发布具有compute_jacvec_product 的组件的代码,我可以就在这种情况下如何处理偏导数给出更详细的建议。

      【讨论】:

      • 感谢您向我指出这一点。这是 gist 中的代码:gist.github.com/mlauryn/f4d3f48549617110bb4f52de0141d98d 实际上我使用 compute_jacvec_product 的原因是它在计算矩阵 wrt 到矩阵的导数方面对我来说更直观。您能否就如何根据输入矩阵变量计算矩阵输出的部分给出一些建议?
      • 我被问过几次这个问题,所以我制作了一个简短的视频,带您完成整个过程:youtu.be/7c4UJ-meHNY
      • 感谢支持和视频!实际上,我昨天运行了代码并将耦合组中的所有组件替换为稀疏部分。性能提升令人印象深刻:)
      猜你喜欢
      • 2021-01-23
      • 1970-01-01
      • 1970-01-01
      • 2023-01-20
      • 1970-01-01
      • 2020-07-14
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多