我正在使用“组件”来“包装” MDO Lab的Openaerostruct。当我宣布
self.deriv_options['type'] = 'fd'
在组件构造函数中,我不必声明“ linearize”方法,并且效果很好。但是我认为通过这样做,我并没有使用“整个” Openaerostruct功能,因为该代码已经实现了“线性化方法”,应该(我认为)可以提高代码的性能。
因此,我正在尝试设置以下内容:
def linearize(self, params, unknowns, resids):
self.OAS_prob.prob.calc_gradient(params,unknowns,mode='rev')
也尝试过:
def linearize(self, params, unknowns, resids):
self.OAS_prob.prob.calc_gradient(indep_list= ['alpha','taper'], unknown_list=['CL','CD'],mode='rev')
和:
def linearize(self, params, unknowns, resids):
taper = params['taper']
alpha = params['alpha']
CD= unknowns['CD']
CL = unknowns['CL']
self.OAS_prob.prob.calc_gradient(indep_list= [taper,alpha], unknown_list=[CD,CL],mode='rev')
但是我遇到以下错误:
Can't determine size of unknowns ['CD', 'CL']
Can't determine size of unknowns [0.09583431121084045, 0.015186066036484149] ## for the last one
我有两个问题:
1-是否可以在组件而不是组中使用“ calc_gradient”,还是我尝试了一些不可能的事情?
2-如果第一个是肯定的,我应该期待某种性能上的改进,因为Openaerostruct已经实现了“线性化”方法?
提前谢谢!
Ps:我想做的事情类似于以下简单示例:
class Aero_Struct(Component):
def __init__(self):
super(Aero_Struct, self).__init__()
self.add_param('taper', val=0.)
self.add_param('alpha', val=0.)
self.add_output('CD', val=0.)
self.add_output('CL', val=0.)
prob_dict = {'type' : 'aero',
'v':30.,
'optimize' : False}
self.OAS_prob = OASProblem(prob_dict)
surf_dict = {'num_y' : 7,
'num_x' : 2,
'wing_type' : 'rect',
'alpha': 2.,
'CD0' : 0.015,
'symmetry' : True,
'num_twist_cp' : 5,
'taper': 0.5,
'num_thickness_cp' : 2}
self.OAS_prob.add_surface(surf_dict)
self.deriv_options['type'] = 'fd'
self.OAS_prob.setup()
def solve_nonlinear(self, params, unknowns, resids):
taper = params['taper']
self.OAS_prob.prob['wing.taper'] = taper
alpha = params['alpha']
self.OAS_prob.prob['alpha'] = alpha
self.OAS_prob.run()
unknowns['CD'] = self.OAS_prob.prob['wing_perf.CD']
unknowns['CL'] = self.OAS_prob.prob['wing_perf.CL']
答案 0 :(得分:1)
正确的是,将派生类型声明为“ fd”会限制您的性能,而不会利用OAS的更高效派生功能。
在正确的方向上,线性化是要定义的函数,并且需要在OAS openmdao模型上计算导数并将其返回。在简单的openmdao 1.7x模型中,线性化效果如下:
def linearize(self, params, unknowns, resids):
""" Jacobian for Sellar discipline 1."""
J = {}
J['y','x'] = 1.0
return J
您需要将从子openmdao的calc_gradient返回的派生打包到J字典中并返回。 如果您在OAS_prob中使用的名称与AeroStruct comp中使用的名称或名称不同,则可能必须转换某些参数或未知名称(例如,根据您的代码,看起来在OAS子模型中锥度为wing.taper。)>
总的来说,它看起来可能更像这样。
def linearize(self, params, unknowns, resids):
derivs = self.OAS_prob.prob.calc_gradient(indep_list= ['alpha', 'wing.taper'], unknown_list=['wing_perf.CL','wing_perf.CD'], mode='rev')
J = {}
J['CL', 'alpha'] = derivs['wing_perf.CL']['alpha']
J['CL', 'taper'] = derivs['wing_perf.CL']['wing.taper']
J['CD', 'alpha'] = derivs['wing_perf.CD']['alpha']
J['CD', 'taper'] = derivs['wing_perf.CD']['wing.taper']
return J
因此,主要是您忘记了从子问题中的calc_gradient调用中解包衍生产品,并将其返回给外部openmdao。