如何将一个复杂的模型分解成组件+自定义"drivers"?

How to break down a complex model into components + custom "drivers"?

我有一个复杂的模型 (A),可以轻松地将其写入具有输入和输出的单个组件中。但是,在模型 A 中,重复调用了两个 "physical" 规程 A1 和 A2。 我想将模型 A 分成两个子组件(A1 和 A2),并有一个根据某些规则调用 A1 和 A2 的代码。 问题是,我应该把这个 "glue code" 写成一个调用它里面其他组件的组件吗?或者我应该编写自己的 "driver" 来使用我的规则调用 A1 和 A2 吗? 还是我必须将大型模型保留在一个组件中?

另一个类似的情况是,必须在不同情况(输入值)下评估(理想情况下)单个组件。如何反复调用?或者制作一个在计算方法内循环的组件? 谢谢

您在这里有多种选择,并且根据您重复调用 A1 和 A2 的原因的详细信息,我建议更改哪一种。

我几乎总是建议将较大的模型分解为较小的组件,因为这样可以更轻松地计算分析导数并提供更加模块化的代码库。假设你确实拆散了 A,重复调用的特征是什么?

A1 和 A2 是您希望在多个不同操作点重复的某种分析吗?例如多个负载情况或空气动力学条件?也许你对它们进行平均以计算 A 的一些最终输出?如果是这样,我建议将 A1 和 A2 编写为向量化函数,它们可以接收输入数据数组(数组的每个条目代表一个不同的点),然后输出一个数组,其中对每个元素进行了计算。以这种方式使用 numpy 数组可以在 OpenMDAO 中快速有效地使用内存。这绝对是我建议你如何处理你的最后一个问题,关于 运行 重复使用不同的输入。如果您不能对函数进行向量化,那么您可以去除模型的多个实例(每个输入案例一个),但是这可能会降低效率,具体取决于您拥有的输入案例数量。

您是否正在迭代 A1/A2 以实现某种收敛过程?如果是这样,您应该使用求解器来处理这种循环。 GaussSeidel 或 Newton 应该可以解决问题。如果您的规则由某种启发式迭代组成以达到收敛,那么您可以将其编码到自定义求解器中,尽管这对于新手用户来说肯定有些困难。相反,如果您的规则相当于某种算法,您以某种固定顺序执行 A1/A2 并按固定次数调用每个算法,那么我回到我的建议,您只需实例化 A1 和 A2 的多个副本,然后将它们连接在一起以制作您想要解决问题的顺序。