openmdao能否在不明确定义的情况下跨Matlab ExternalCodeComp计算偏导数?

2024-10-03 00:20:33 发布

您现在位置:Python中文网/ 问答频道 /正文

是否可以让openmdao使用有限差分法来近似整个ExternalCodeComp的偏导数

仅仅使用方法self.declare_partials('*','*', method='fd')似乎不起作用 优化在1次迭代后收敛,仅使用1个函数和梯度求值

弹出的错误提示: 派生警告:约束或目标[('p.f_xy',inds=[0])]不能受到问题的设计变量的影响。 派生警告:设计变量[('p.x',inds=[0]),('p.y',inds=[0])]对约束或目标没有影响。 优化已成功终止


Tags: 方法函数self警告目标method梯度导数
1条回答
网友
1楼 · 发布于 2024-10-03 00:20:33

作为OpenMDAO测试套件的一部分,我们运行了一个与此非常类似的测试用例。您的declare_partials调用不太正确,因为您将前两个参数列为“”和“”,这两个参数与任何变量名都不匹配。我怀疑这只是你文章中的一个输入错误,因为如果你在使用这些参数时实际运行OpenMDAO,你会得到一个异常,告诉你声明的部分与任何变量都不匹配。在下面的示例中,我将部分声明为self.declare_partials(of='*', wrt='*', method='fd')。假设您的部分实际上声明正确,我的猜测是,出于某种原因,您的外部代码生成的输出文件要么根本没有得到更新,要么您总是将相同的值写入输出文件。下面是计算抛物面的外部代码的工作示例。希望这能帮助你找到问题所在。如果没有,你可以尝试在这里发布你的代码,我们可以从那里开始

以下是OpenMDAO脚本:


import sys
import openmdao.api as om


class ParaboloidExternalCodeCompFD(om.ExternalCodeComp):
    def setup(self):
        self.add_input('x', val=0.0)
        self.add_input('y', val=0.0)

        self.add_output('f_xy', val=0.0)

        self.input_file = 'paraboloid_input.dat'
        self.output_file = 'paraboloid_output.dat'

        # providing these is optional; the component will verify that any input
        # files exist before execution and that the output files exist after.
        self.options['external_input_files'] = [self.input_file]
        self.options['external_output_files'] = [self.output_file]

        self.options['command'] = [
            sys.executable, 'extcode_paraboloid.py', self.input_file, self.output_file
        ]

    def setup_partials(self):
        # this external code does not provide derivatives, use finite difference
        self.declare_partials(of='*', wrt='*', method='fd')

    def compute(self, inputs, outputs):
        x = inputs['x']
        y = inputs['y']

        # generate the input file for the paraboloid external code
        with open(self.input_file, 'w') as input_file:
            input_file.write('%.16f\n%.16f\n' % (x, y))

        # the parent compute function actually runs the external code
        super().compute(inputs, outputs)

        # parse the output file from the external code and set the value of f_xy
        with open(self.output_file, 'r') as output_file:
            f_xy = float(output_file.read())

        outputs['f_xy'] = f_xy


prob = om.Problem()
model = prob.model

model.add_subsystem('p', ParaboloidExternalCodeCompFD())

# find optimal solution with SciPy optimize
# solution (minimum): x = 6.6667; y = -7.3333
prob.driver = om.ScipyOptimizeDriver()
prob.driver.options['optimizer'] = 'SLSQP'

prob.model.add_design_var('p.x', lower=-50, upper=50)
prob.model.add_design_var('p.y', lower=-50, upper=50)

prob.model.add_objective('p.f_xy')

prob.driver.options['tol'] = 1e-9
prob.driver.options['disp'] = True

prob.setup()

# Set input values
prob.set_val('p.x', 3.0)
prob.set_val('p.y', -4.0)

prob.run_driver()

print('p.x =', prob.get_val('p.x'), "  expected:", [6.66666667])
print('p.x =', prob.get_val('p.y'), "  expected:", [-7.3333333])

下面是名为extcode_paraboloid.py的外部代码脚本:

#!/usr/bin/env python
#
# usage: extcode_paraboloid.py input_filename output_filename
#
# Evaluates the equation f(x,y) = (x-3)^2 + xy + (y+4)^2 - 3.
#
# Read the values of `x` and `y` from input file
# and write the value of `f_xy` to output file.

if __name__ == '__main__':
    import sys

    input_filename = sys.argv[1]
    output_filename = sys.argv[2]

    with open(input_filename, 'r') as input_file:
        file_contents = input_file.readlines()

    x, y = [float(f) for f in file_contents]

    f_xy = (x-3.0)**2 + x*y + (y+4.0)**2 - 3.0

    with open(output_filename, 'w') as output_file:
        output_file.write('%.16f\n' % f_xy)

如果将它们放在同一个目录中并运行OpenMDAO脚本,则应得到如下结果:

Optimization terminated successfully.    (Exit mode 0)
            Current function value: -27.333333333333
            Iterations: 5
            Function evaluations: 6
            Gradient evaluations: 5
Optimization Complete
                 -
p.x = [6.66666633]   expected: [6.66666667]
p.x = [-7.33333367]   expected: [-7.3333333]

相关问题 更多 >