openmdao 可以在没有明确定义的情况下计算 Matlab ExternalCodeComp 的偏导数吗?

问题描述

是否有可能让 openmdao 使用有限差分来逼近 ExternalCodeComp 上的偏导数。

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

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

解决方法

作为 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='*',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',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'),[-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]

相关问答

Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其...
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。...
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbc...