1

我目前正在模拟一个结构优化问题,其中响应的梯度从 Nastran 中提取并提供给 OpenMDAO 中的 SLSQP 优化器。在后续迭代中约束的数量会发生变化,因为设计变量包括形状和尺寸变量,因此每次都会生成一个新的网格。OpenMDAO 中定义了一个约束组件,它读取从 Nastran 导出的响应数据。现在,这里的问题在于定义其输出变量“f_const”的形状。此输出变量的形状需要根据可用响应数组的形状进行调整,因为输出['f_const'] = np.loadtxt("nsatran_const.dat")。这里,nastran_const.dat 是包含从 Nastran 提取的响应数据的文件。该数据的形状在设计迭代开始时是未知的,并在随后的迭代中不断变化。因此,如果在开始时定义了某种形状的 f_const,那么它以后不会更改并且由于形状不匹配而产生错误。

在 openmdao 的文档中,我找到了https://openmdao.org/newdocs/versions/latest/features/experimental/dyn_shapes.html?highlight=varying%20shape 它解释说,输入/输出变量的形状可以动态设置通过将其链接到形状已知的任何连接变量或局部变量。这与我的情况不同,因为在计算开始之前,应力阵列的形状是未知的。f_const 的形状要在 setup 中定义,我不知道以后如何更改它。请在这方面指导我。

4

1 回答 1

1

你不能有像那样改变形状的数组。您在文档中找到的“动态”形状是指设置时间变化。但是,一旦设置完成,尺寸就固定了。因此,我们需要一种方法让您的数组具有固定大小。

如果您真的必须每次都重新网格化(我不推荐),那么我可以想到两种可能的解决方案:

  1. 超额分配
  2. 约束聚合

选项 1——过度分配

此相关问题中详细介绍了该主题,但简要地说,您可以做的是分配一个足够大的数组,以便您始终有足够的空间。然后您可以使用数组的一个条目来记录其中有多少活动条目。任何非活动条目都将设置为不会违反您的约束的默认值。

您必须非常小心定义导数的方式。对于活动数组条目,派生数来自 NASTRAN。对于非活动的,您可以将它们设置为 0,但请注意,当条目切换到活动时,您正在创建离散的不连续性。当优化器试图收敛并且活动约束的导数不断在 0 和非零值之间翻转时,这可能会很好地适应优化器。

我真的不推荐这种方法,但如果你绝对必须有“可变大小”数组,那么过度分配是你最好的选择。

选项 2——约束聚合

他们这里的关键思想是使用聚合函数将所有压力约束折叠成一个值。对于结构问题,这通常使用 KS 函数来完成。OpenMDAO在其标准库中有一个可以使用的 KS 组件。

关键是这个组件需要一个恒定大小的输入。因此,这里将再次使用过度分配。在这种情况下,您不应该跟踪数组中活动值的数量,因为您将其传递给聚合函数。KS 函数就像平滑的最大值函数,所以如果你有一堆 0,那么它不应该影响它。

您的问题仍然有一个不连续的操作,重新划分网格和嘈杂的约束数组。KS 函数应该平滑其中的一些,但不是全部。我仍然认为你会难以收敛,但它应该比原始的过度分配更好。

选项 3 --- “正确”答案 找到修复网格的方法,使其永不改变。我知道如果你使用 VSP 来生成你的分类,并让 NASTRAN 从那里重新网格化东西,这很难……但这并不是不可能的。

OpenVSP 有一组几何查询函数,可用于将固定网格反向拟合到几何的参数空间中。如果你这样做,那么你可以在 VSP 中重新生成几何图形并使用参数空间来移动你的固定网格。密歇根大学 MDO 实验室的pyGeo工具就是这样做的,而且效果很好。

它的工作量适中(虽然如果你直接使用 pyGeo 会少很多),但我认为它非常值得。您将获得更快的组件和更稳定的优化。

于 2022-01-17T16:01:44.380 回答