SLSQP 不将阵列作为设计变量驱动

SLSQP does not drive array as a design variable

我是openmdao的新手。最近我正在尝试实现一个虚拟机翼优化问题来学习 openmdao。我想出了一个奇怪的问题,我想问一下。我正在使用 bspline 来定义扭曲和 t/c 分布。当我使用 COBYLA、DifferentialEvolution 或 DOEdriver 作为驱动程序时,优化设置正在运行。但是当我设置 SciPy SLSQP 时,这些样条曲线的控制点在迭代过程中不会改变。可能是什么问题?

下面是我定义问题的主要部分...

if __name__ == '__main__':
    
    driver = om.ScipyOptimizeDriver() ;   
    driver.options['optimizer']='SLSQP' 
    
    driver = om.DOEDriver(om.LatinHypercubeGenerator(samples=10))
       
    
    recorder_name ='cases'
    recorder = om.SqliteRecorder(recorder_name+'.sql')
    
    driver = om.DifferentialEvolutionDriver()
    driver.options['max_gen']=10
    
     
    
    min_step = 0.01
    n_cp = 4
    n_vsp_segment = 4
    
    ivc = om.IndepVarComp()
    ivc.add_output('Mach',0.2)
    ivc.add_output('b',7.)
    ivc.add_output('cr',3.)
    ivc.add_output('taper',0.5)
    ivc.add_output('twist_cp',np.ones(n_cp))
    ivc.add_output('tc_cp',np.ones(n_cp)*0.1)
    
    Scomp = om.SplineComp(method='bsplines',x_interp_val = np.linspace(0.,1.,int(n_vsp_segment)),
                          num_cp = n_cp, interp_options={"order": min(n_cp, 4)})
    Scomp.add_spline(y_cp_name='twist',y_interp_name='twist_vsp')
    Scomp.add_spline(y_cp_name='tc',y_interp_name='tc_vsp')
       
    
    model = om.Group()
    model.add_subsystem('IVC',ivc)
    model.add_subsystem('spline',Scomp)    
    model.add_subsystem('VSP',VSP(n_vsp_segment=n_vsp_segment))  
    model.add_subsystem('AVL',AVL())    
    model.add_subsystem('obj',om.ExecComp('obj = (CD0+CDi)*100+0.1/tr'))
    model.add_subsystem('cons',om.ExecComp('c1 = Sref-40.'))
    
    model.connect('IVC.twist_cp','spline.twist')
    model.connect('spline.twist_vsp','VSP.twist')
    
    model.connect('IVC.tc_cp','spline.tc')
    model.connect('spline.tc_vsp','VSP.tc')
    
    model.connect('IVC.Mach',['VSP.Mach','AVL.Mach'])
    model.connect('IVC.b',['VSP.b','AVL.b'])
    model.connect('IVC.cr','VSP.cr')
    model.connect('IVC.taper','VSP.taper')
    
    model.connect('VSP.CD0','obj.CD0')
    model.connect('VSP.Sref',['AVL.Sref','cons.Sref'])
    model.connect('VSP.Cref','AVL.Cref')
    model.connect('VSP.MOMref','AVL.MOMref')
    model.connect('VSP.tr','obj.tr')
    
    model.connect('AVL.CDi','obj.CDi') 
    
    
    prob = om.Problem(model,driver)
    prob.model.add_design_var('IVC.tc_cp',lower=0.05,upper=0.1,indices=[1,2,3])
    prob.model.add_design_var('IVC.twist_cp',lower=-10.,upper=2.,indices=[1,2,3])
    prob.model.add_design_var('IVC.cr',lower=2,upper=6)
    prob.model.add_design_var('IVC.b',lower=10,upper=20)
    prob.model.add_design_var('IVC.taper',lower=0.2,upper=0.9) 
    prob.model.add_constraint('cons.c1',upper=0)
    prob.model.add_objective('obj.obj',scaler=100)
    
    prob.setup(check=True)
      
    prob.set_val('IVC.cr',4.)
    prob.set_val('IVC.b',10.)
    prob.set_val('IVC.taper',0.8)
    
    prob.driver.options['debug_print'] = ['desvars','ln_cons','nl_cons','objs']
    
    prob.run_driver()

您的问题似乎与无梯度方法有关,但与基于梯度的方法无关。因此可以肯定的是,衍生品存在问题。

我将假设,由于您使用的是 VSP 和 AVL,因此您正在做有限差分。您可能需要设置不同的 FD 设置以获得合适的导数近似值。您可能想在问题的顶层使用 [appox_totals][1] 方法。

您可能需要尝试使用更大的 FD 步长以及绝对步长和相对步长。您可以使用 OpenMDAO scaling report. 直观地了解您的初始 jacobian 看起来像什么 乍一看您的问题看起来并没有严重缩放,但是该报告中的 jacobian 可视化可能对您测试 FD 步长有帮助。