openmdao: ограничение не существует и ошибка значения в коде

Я создавал проект по оптимизации формы самолета для минимального сопротивления, и столкнулся с двумя проблемами: одна возникает с примененным ограничением, и я получил следующую ошибку

 File "/home/name/Desktop/x1ac3opt.py", line 202, in <module>
    top.setup()

  File "/usr/local/lib/python2.7/dist-packages/openmdao/core/problem.py", line 498, in setup
    connections = self._setup_connections(params_dict, unknowns_dict)

  File "/usr/local/lib/python2.7/dist-packages/openmdao/core/problem.py", line 197, in _setup_connections
    connections = self.root._get_explicit_connections()

  File "/usr/local/lib/python2.7/dist-packages/openmdao/core/group.py", line 685, in _get_explicit_connections
    (src, tgt, tgt))

NameError: Source 'p.Sp1' cannot be connected to target 'con.Sp1': 'con.Sp1' does not exist.

и это происходит с ограничениями, указанными в `

File "/home/name/Desktop/x1ac3opt.py", line 63, in solve_nonlinear
    unknowns['Cdi'] = (324/((7750)*(m.pi)*(((Sp1+Sp2+Sp3+Sp4+Sp5)**2)/(Sp1*(Rc+Tc1)/2+Sp2*(Tc1+Tc2)/2+Sp3*(Tc2+Tc3)/2+Sp4*(Tc3+Tc4)/2+Sp5*(Tc4+Tc5)/2))))

  File "/usr/local/lib/python2.7/dist-packages/openmdao/core/vec_wrapper.py", line 435, in __setitem__
    self._dat[name].set(value)

  File "/usr/local/lib/python2.7/dist-packages/openmdao/core/vec_wrapper.py", line 313, in _set_scalar
    self.val[0] = value

ValueError: setting an array element with a sequence.

`

есть идеи о том, почему это происходит?

РЕДАКТИРОВАТЬ: вот весь код

`# Для печати используйте этот импорт, если вы используете Python 2.x из будущего import print_function

импортировать математику как m

из openmdao.api импортировать IndepVarComp, Component, Problem, Group, ExecComp, ScipyOptimizer, SqliteRecorder

class Outershell (Компонент): "" "Компонент, содержащий Outershell." ""

def __init__(self):
    super(Outershell, self).__init__()
    self.add_param('Sp1', val=23)      #Sec1Span
    self.add_param('Sp2', val=13)      #Sec2Span
    self.add_param('Sp3', val=20)      #Sec3Span
    self.add_param('Sp4', val=35)      #Sec4Span
    self.add_param('Sp5', val=35)      #Sec5Span

    self.add_param('Sw1', val=60)      #Sec1Sweep
    self.add_param('Sw2', val=60)      #Sec2sweep
    self.add_param('Sw3', val=50)      #Sec3sweep
    self.add_param('Sw4', val=37)      #Sec4sweep
    self.add_param('Sw5', val=35)      #Sec5sweep

    self.add_param('Rc', val=130)      #Sec1RC
    self.add_param('Tc1', val=90)      #Sec1TC
    self.add_param('Tc2', val=66)      #Sec2TC
    self.add_param('Tc3', val=42)     #Sec3TC
    self.add_param('Tc4', val=24)      #Sec4TC
    self.add_param('Tc5', val=10)      #Sec5TC

    self.add_output('Cdi', shape=1)     #Objective output as low as possible


def solve_nonlinear(self, params, unknowns, resids):

    #0.0324 and 0.775 are the squared Cl and the oswald efficiency number in the case that I can find a way to add in those values to the optimization problem

    Sp1 = params['Sp1']
    Sp2 = params['Sp2']
    Sp3 = params['Sp3']
    Sp4 = params['Sp4']
    Sp5 = params['Sp5']

    Sw1 = params['Sw1']
    Sw2 = params['Sw2']
    Sw3 = params['Sw3']
    Sw4 = params['Sw4']
    Sw5 = params['Sw5']

    Rc = params['Rc']
    Tc1 = params['Tc1']
    Tc2 = params['Tc2']
    Tc3 = params['Tc3']
    Tc4 = params['Tc4']
    Tc5 = params['Tc5']


    unknowns['Cdi'] = (324/((7750)*(m.pi)*(((Sp1+Sp2+Sp3+Sp4+Sp5)**2)/(Sp1*(Rc+Tc1)/2+Sp2*(Tc1+Tc2)/2+Sp3*(Tc2+Tc3)/2+Sp4*(Tc3+Tc4)/2+Sp5*(Tc4+Tc5)/2))))


def linearize(self, params, unknowns, resids):


    Sp1 = params['Sp1']
    Sp2 = params['Sp2']
    Sp3 = params['Sp3']
    Sp4 = params['Sp4']
    Sp5 = params['Sp5']

    sw1 = params['Sw1']
    sw2 = params['Sw2']
    sw3 = params['Sw3']
    sw4 = params['Sw4']
    sw5 = params['Sw5']

    Rc = params['Rc']
    Tc1 = params['Tc1']
    Tc2 = params['Tc2']
    Tc3 = params['Tc3']
    Tc4 = params['Tc4']
    Tc5 = params['Tc5']

    J ={}
    J['Cdi', 'Sp1']=unknowns['Cdi']/Sp1
    J['Cdi', 'Sp2']=unknowns['Cdi']/Sp2
    J['Cdi', 'Sp3']=unknowns['Cdi']/Sp3
    J['Cdi', 'Sp4']=unknowns['Cdi']/Sp4
    J['Cdi', 'Sp5']=unknowns['Cdi']/Sp5
    J['Cdi', 'Sw1']=unknowns['Cdi']/sw1
    J['Cdi', 'Sw2']=unknowns['Cdi']/sw2
    J['Cdi', 'Sw3']=unknowns['Cdi']/sw3
    J['Cdi', 'Sw4']=unknowns['Cdi']/sw4
    J['Cdi', 'Sw5']=unknowns['Cdi']/sw5
    J['Cdi', 'Tc1']=unknowns['Cdi']/Tc1
    J['Cdi', 'Tc2']=unknowns['Cdi']/Tc2
    J['Cdi', 'Tc3']=unknowns['Cdi']/Tc3
    J['Cdi', 'Tc4']=unknowns['Cdi']/Tc4
    J['Cdi', 'Tc5']=unknowns['Cdi']/Tc5
    J['Cdi', 'Rc']=unknowns['Cdi']/Rc

if __name__ == "__main__":

top = Problem()

root = top.root = Group()

root.add('p1', IndepVarComp('Sp1', 23))
root.add('p2', IndepVarComp('Sp2', 13))
root.add('p3', IndepVarComp('Sp3', 20))
root.add('p4', IndepVarComp('Sp4', 35))
root.add('p5', IndepVarComp('Sp5', 35))
root.add('p6', IndepVarComp('Sw1', 60))
root.add('p7', IndepVarComp('Sw2', 60))
root.add('p8', IndepVarComp('Sw3', 50))
root.add('p9', IndepVarComp('Sw4', 37))
root.add('p10', IndepVarComp('Sw5', 35))
root.add('p11', IndepVarComp('Tc1', 90))
root.add('p12', IndepVarComp('Tc2', 66))
root.add('p13', IndepVarComp('Tc3', 42))
root.add('p14', IndepVarComp('Tc4', 24))
root.add('p15', IndepVarComp('Tc5', 10))
root.add('p16', IndepVarComp('Rc', 130))
root.add('p', Outershell())


root.add('con', ExecComp('L = (15067/100000000)/(Sp1(Rc+Tc1)/2+Sp2(Tc1+Tc2)/2+Sp3(Tc2+Tc3)/2+Sp4(Tc3+Tc4)/2+Sp5(Tc4+Tc5)/2)'))
 #Cl=0.18 rho = 0.000737 v**2 = 810471.67 Area = ... 597.31762079


root.connect('p1.Sp1', 'p.Sp1')
root.connect('p2.Sp2', 'p.Sp2')
root.connect('p3.Sp3', 'p.Sp3')
root.connect('p4.Sp4', 'p.Sp4')
root.connect('p5.Sp5', 'p.Sp5')
root.connect('p6.Sw1', 'p.Sw1')
root.connect('p7.Sw2', 'p.Sw2')
root.connect('p8.Sw3', 'p.Sw3')
root.connect('p9.Sw4', 'p.Sw4')
root.connect('p10.Sw5', 'p.Sw5')
root.connect('p11.Tc1', 'p.Tc1')
root.connect('p12.Tc2', 'p.Tc2')
root.connect('p13.Tc3', 'p.Tc3')
root.connect('p14.Tc4', 'p.Tc4')
root.connect('p15.Tc5', 'p.Tc5')
root.connect('p16.Rc', 'p.Rc')

root.connect('p.Sp1', 'con.Sp1')
root.connect('p.Sp2', 'con.Sp2')
root.connect('p.Sp3', 'con.Sp3')
root.connect('p.Sp4', 'con.Sp4')
root.connect('p.Sp5', 'con.Sp5')
root.connect('p.Sw1', 'con.Sw1')
root.connect('p.Sw2', 'con.Sw2')
root.connect('p.Sw3', 'con.Sw3')
root.connect('p.Sw4', 'con.Sw4')
root.connect('p.Sw5', 'con.Sw5')
root.connect('p.Tc1', 'con.Tc1')
root.connect('p.Tc2', 'con.Tc2')
root.connect('p.Tc3', 'con.Tc3')
root.connect('p.Tc4', 'con.Tc4')
root.connect('p.Tc5', 'con.Tc5')
root.connect('p.Rc', 'con.Rc')



top.driver = ScipyOptimizer()
top.driver.options['optimizer'] = 'COBYLA'


top.driver.add_desvar('p1.Sp1', lower=13, upper=33)
top.driver.add_desvar('p2.Sp2', lower=3, upper=23)
top.driver.add_desvar('p3.Sp3', lower=10, upper=30)
top.driver.add_desvar('p4.Sp4', lower=25, upper=45)
top.driver.add_desvar('p5.Sp5', lower=25, upper=45)
top.driver.add_desvar('p6.Sw1', lower=55, upper=65)
top.driver.add_desvar('p7.Sw2', lower=55, upper=65)
top.driver.add_desvar('p8.Sw3', lower=45, upper=55)
top.driver.add_desvar('p9.Sw4', lower=32, upper=42)
top.driver.add_desvar('p10.Sw5', lower=30, upper=40)
top.driver.add_desvar('p11.Tc1', lower=80, upper=100)
top.driver.add_desvar('p12.Tc2', lower=56, upper=76)
top.driver.add_desvar('p13.Tc3', lower=37, upper=45)
top.driver.add_desvar('p14.Tc4', lower=19, upper=29)
top.driver.add_desvar('p15.Tc5', lower=5, upper=15)
top.driver.add_objective('p.Cdi')
top.driver.add_constraint('con.L', lower=220000, upper=240000)


recorder = SqliteRecorder('Outershell')
recorder.options['record_params'] = True
recorder.options['record_metadata'] = True
top.driver.add_recorder(recorder)

top.setup()
top.run()
top.cleanup()  # this closes all recorders


print('\n')
print('Minimum of %f found at: ' % (top['p.Cdi']))
print('\n')
print('Lift produced is: %f ' % (top['con.L']))
print('SP1 = %f' % (top['p.Sp1']))
print('\n')
print('SP2 = %f' % (top['p.Sp2']))
print('\n')
print('SP3 = %f' % (top['p.Sp3']))
print('\n')
print('SP4 = %f' % (top['p.Sp4']))
print('\n')
print('SP5 = %f' % (top['p.Sp5']))
print('\n')
print('SW1 = %f' % (top['p.Sw1']))
print('\n')
print('SW2 = %f' % (top['p.Sw2']))
print('\n')
print('SW3 = %f' % (top['p.Sw3']))
print('\n')
print('SW4 = %f' % (top['p.Sw4']))
print('\n')
print('SW5 = %f' % (top['p.Sw5']))
print('\n')
print('Rc = %f' % (top['p.Rc']))
print('\n')
print('TC1 = %f' % (top['p.Tc1']))
print('\n')
print('TC2 = %f' % (top['p.Tc2']))
print('\n')
print('TC3 = %f' % (top['p.Tc3']))
print('\n')
print('TC4 = %f' % (top['p.Tc4']))
print('\n')
print('TC5 = %f' % (top['p.Tc5']))
print('\n')

`


person samf    schedule 26.09.2017    source источник


Ответы (2)


По первой ошибке:

L = (15067/100000000)/(Sp1(Rc+Tc1)/2+Sp2(Tc1+Tc2)/2+Sp3(Tc2+Tc3)/2+Sp4(Tc3+Tc4)/2+Sp5(Tc4+Tc5)/2)')

Я думаю, вам нужно явно указать умножение, поэтому

L = (15067/100000000)/(Sp1*(Rc+Tc1)/2+Sp2*(Tc1+Tc2)/2+Sp3*(Tc2+Tc3)/2+Sp4*(Tc3+Tc4)/2+Sp5*(Tc4+Tc5)/2)')
person Kenneth Moore    schedule 28.09.2017
comment
Это сработало, но похоже, что одна из предыдущих ошибок немного изменилась и теперь читает `File /usr/local/lib/python2.7/dist-packages/openmdao/core/_checks.py, строка 97, в типе _check_types_match (tval), _both_names (tgt, to_prom_name))) TypeError: Type ‹type 'int'› источника 'p16.Rc' должен быть таким же, как type ‹type 'float'› target 'con.Rc'. - person samf; 29.09.2017
comment
вы также хотите, чтобы ваши переменные были плавающими: self.add_param('Sp1', val=23.) - person Justin Gray; 29.09.2017
comment
В качестве быстрого вопроса, теперь я получаю результаты, однако они выходят за рамки, которые я указал, я ввел top.driver.add_desvar('p15.Tc5', lower=5., upper=15.), и он выдает отрицательное значение. может ли это быть результатом использования root.add('p15', IndepVarComp('Tc5', 1.)) и, как часть этого, какова цель значения после имени параметра, который я ввел? - person samf; 29.09.2017
comment
Значение в indepvarcomp - это начальное значение переменной (здесь p15.Tc5). Я не уверен, почему Cobyla вынуждает его выходить за рамки ограничений, но вы можете включить более подробный вывод, чтобы увидеть, что он делает. - person Kenneth Moore; 29.09.2017
comment
Интересно, что изменение оптимизатора на Nedler-Mead, похоже, исправило ошибки ... - person samf; 02.10.2017

По первой ошибке:

не видя вашей реальной модели, я не могу понять, почему это происходит. Но вы пытаетесь подключить (как я предполагаю) выход IndepVarComp к входу какого-то другого компонента (возможно, exec comp). Вы, вероятно, продвинули источник, цель или их обоих. Таким образом, вы не называете их именами, которые верны с учетом рекламных акций.

Если вы уже повысили обе переменные, так как обе являются именами Sp1, они автоматически подключаются. Если вы продвинули только одного из них, вам необходимо учесть это в операторе подключения. Например:

self.connect('Sp1', 'con.Sp1')

Для вашей второй ошибки: существует какое-то несоответствие размера между Cdi и уравнением, которое вам нужно для вычисления значения. Похоже, что это уравнение может быть скалярным, но я не могу сказать наверняка, потому что не знаю, что такое промежуточные переменные. В любом случае, та или иная сторона этого задания не соответствует размеру. Вы можете отладить это, добавив несколько операторов печати, чтобы увидеть, какого размера вещи OpenMDAO.

print(unknowns['Cdi'])
print((324/((7750)*(m.pi)*(((Sp1+Sp2+Sp3+Sp4+Sp5)**2)/(Sp1*(Rc+Tc1)/2+Sp2*(Tc1+Tc2)/2+Sp3*(Tc2+Tc3)/2+Sp4*(Tc3+Tc4)/2+Sp5*(Tc4+Tc5)/2))))))
person Justin Gray    schedule 27.09.2017
comment
отсутствует ссылка или что-то в этом роде? Я не вижу нового кода - person Justin Gray; 28.09.2017
comment
Просто добавил это в исходный вопрос - person samf; 28.09.2017