我无法记录/访问衍生产品2

时间:2019-03-06 07:57:49

标签: openmdao

作为此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())

1 个答案:

答案 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)。