如何解决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]
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。