作为此question的继续,我添加了一个伪代码,使用该伪代码很难访问派生类。 我还添加了comp变量。这只是转换问题的标志 带有显式组件或包含显式组件的组。
from openmdao.api import Problem, ScipyOptimizeDriver, ExecComp, IndepVarComp, SqliteRecorder, CaseReader
from openmdao.api import Group
from openmdao.api import ExplicitComponent
comp=True
class Exp(ExplicitComponent):
def setup(self):
self.add_input('des1',val=1)
self.add_input('des2',val=1)
self.add_output('out',val=1)
self.add_output('con',val=1)
self.declare_partials('*', '*',method='fd',step=0.001)
def compute(self, inputs, outputs):
outputs['out']=inputs['des1']**2+inputs['des2']
outputs['con']=inputs['des1']
class AERO(Group):
def setup(self):
self.add_subsystem('Exp',Exp(),promotes=['*'])
infodict={'desvar':{'des1':{"fdstep": 0.1,"init": 1.0,"max": 1.3,"min": 0.8},
'des2':{"fdstep": 0.1,"init": 2.0,"max": 1.3,"min": 0.8}}}
prob = Problem()
probname = prob.model = Group()
recordername='recorder1.sql'
GLOBAL_DESIGN_VAR = IndepVarComp()
probname.add_subsystem('GLOBAL_DESIGN_VAR', GLOBAL_DESIGN_VAR,promotes=['*'])
if comp:
probname.add_subsystem('Exp', Exp(),promotes=['*'])
else:
probname.add_subsystem('AERO', AERO(),promotes=['*'])
for key,val in infodict['desvar'].items():
GLOBAL_DESIGN_VAR.add_output(key, val['init'])
probname.add_design_var(key,lower=val['min'], upper=val['max'])
probname.add_objective('out')
probname.add_constraint('con',upper=0.1)
prob.driver=ScipyOptimizeDriver()
prob.driver.options['optimizer'] = 'SLSQP'
prob.driver.options['disp'] = True
prob.driver.options['tol'] = 1e-9
recorder = SqliteRecorder(recordername)
prob.driver.add_recorder(recorder)
#prob.driver.recording_options['includes'] = []
#prob.driver.recording_options['record_inputs'] = True
# prob.driver.recording_options['record_outputs'] = True
#prob.driver.recording_options['record_objectives'] = True
#prob.driver.recording_options['record_constraints'] = True
#prob.driver.recording_options['record_desvars'] = True
prob.driver.recording_options['record_derivatives'] = True
prob.setup(check=True)
prob.run_driver()
prob.cleanup()
cr = CaseReader(recordername)
# driver_cases = cr.list_cases('driver')
# Get derivatives associated with the last iteration.
case = cr.get_case(-1)
print(case)
# check that derivatives have been recorded.
print(case.jacobian.keys())
答案 0 :(得分:1)
我稍微整理了一下脚本,但是除了des2
上的初始条件不佳(2.0超出了您的给定范围)之外,优化运行良好。最初的猜测很糟糕,它达到了最大化,并给出了NAN
。无论哪种方式,都记录了导数。
from openmdao.api import Problem, ScipyOptimizeDriver, ExecComp, IndepVarComp, SqliteRecorder, CaseReader
from openmdao.api import Group
from openmdao.api import ExplicitComponent
class Exp(ExplicitComponent):
def setup(self):
self.add_input('des1',val=1)
self.add_input('des2',val=1)
self.add_output('out',val=1)
self.add_output('con',val=1)
self.declare_partials('*', '*',method='fd',step=0.001)
def compute(self, inputs, outputs):
outputs['out']=inputs['des1']**2+inputs['des2']
outputs['con']=inputs['des1']
prob = Problem()
dvs = IndepVarComp()
prob.model.add_subsystem('dvs', dvs, promotes=['*'])
prob.model.add_subsystem('Exp', Exp(),promotes=['*'])
dvs.add_output('des1', 1.0)
prob.model.add_design_var('des1',lower=0.8, upper=1.3)
# dvs.add_output('des2', 2.0) # BAD INITIAL GUESS!!!!!
dvs.add_output('des2', 1.0)
prob.model.add_design_var('des2',lower=0.8, upper=1.3)
prob.model.add_objective('out')
prob.model.add_constraint('con',upper=0.1)
prob.driver=ScipyOptimizeDriver()
prob.driver.options['optimizer'] = 'SLSQP'
prob.driver.options['disp'] = True
prob.driver.options['tol'] = 1e-9
RECORDER_NAME = 'recorder1.sql'
recorder = SqliteRecorder(RECORDER_NAME)
prob.driver.add_recorder(recorder)
#prob.driver.recording_options['includes'] = []
#prob.driver.recording_options['record_inputs'] = True
# prob.driver.recording_options['record_outputs'] = True
#prob.driver.recording_options['record_objectives'] = True
#prob.driver.recording_options['record_constraints'] = True
#prob.driver.recording_options['record_desvars'] = True
prob.driver.recording_options['record_derivatives'] = True
prob.setup(check=True)
prob.run_driver()
prob.cleanup()
cr = CaseReader(RECORDER_NAME)
cases = cr.get_cases()
for c in cases:
print(c.outputs['des1'], c.outputs['des2'])
if c.jacobian is not None:
print(c.jacobian)
print()
运行时给出:
Optimization terminated successfully. (Exit mode 0)
Current function value: 1.4400000000000002
Iterations: 7
Function evaluations: 3
Gradient evaluations: 3
Optimization Complete
-----------------------------------
[1.] [1.]
[1.] [1.]
[0.8] [0.8]
{('out', 'des1'): array([[2.001]]), ('out', 'des2'): array([[1.]]), ('con', 'des1'): array([[1.]]), ('con', 'des2'): array([[-0.]])}
[0.8] [0.8]
{('out', 'des1'): array([[1.601]]), ('out', 'des2'): array([[1.]]), ('con', 'des1'): array([[1.]]), ('con', 'des2'): array([[-0.]])}
请注意,并非每种情况都有与之关联的派生词。行搜索步骤无需重新计算导数,因此不会记录任何内容。在您原始的测试脚本中,最后一个案例没有任何派生,但是前面的一些案例却有(虽然全部都填充了NAN
)。