I'm just get stared at OpenMDAO and multidisciplinary optimization, I'm going to use OpenMDAO to build a CO(Collaborative Optimization) framwork on the classical Sellar problem.
However, when I ran this code I always get the following error:
TypeError: _init_sys_data() missing 1 required positional argument: 'probdata'
which occurs when running the problem.setup()
I've no idear what does this error mean since there's no difference of this line of code to the OpenMDAO standard tut.
Could somebody give me some advices?
Here's the code, some hints from this question
Sellar problem formed as CO:
SystemOpt
min x1**2 + z2 + y1 + eye(-y2)
w.r.t z1, z2, x1, y1, y2
s.t (z1 - z1_d1)**2 + (x1 - x1_d1)**2 + (z2 - z2_d1)**2 + 0.2 * (y2 - y2_d1) <= epsilon
(y2 - y2_d2)**2 + (y1 - y1_d2)**2 + (z1 - z1_d2)**2 + (z2 - z2_d2)**2 <= epsilon
-10 <= z1 <= 10
0 <= z2 <= 10
0 <= x1 <= 10
SobOpt1
min (z1 - z1_d1)**2 + (x1 - x1_d1)**2 + (z2 - z2_d1)**2 + 0.2 * (y2 - y2_d1)
w.r.t z1_d1, x1_d1, z2_d1, y2_d1
s.t z1_d1**2 + x1_d1 + z2_d1 - 0.2 * y2_d1 >= 3.16
0 <= x1_d1 <=10
-10 <= z1_d1 <= 10
0 <= z2_d1 <= 10
SubOpt2
min (y2 - y2_d2)**2 + (y1 - y1_d2)**2 + (z1 - z1_d2)**2 + (z2 - z2_d2)**2
w.r.t y2_d2, y1_d2, z1_d2, z2_d2
s.t y1_d2 ** 0.5 + z1_d2 + z2_d2 <= 24
-10 <= z1_d2 <= 10
0 <= z2_d2 <= 10
from __future__ import print_function
import numpy as np
from openmdao.api import ExecComp, IndepVarComp, Group
from openmdao.api import Component, ScipyOptimizer
class Discipline1(Component):
"""Component containing Discipline 1."""
def __init__(self):
super(Discipline1, self).__init__()
self.add_param('z1_d1', val=0.0)
self.add_param('x1_d1', val=0.)
self.add_param('z2_d1', val=1.0)
self.add_param('y2_d1', val=1.0)
self.add_param('z1', val=1.0)
self.add_param('x1', val=1.0)
self.add_param('z2', val=1.0)
self.add_param('y2', val=1.0)
self.add_param('obj1', val=1.0)
def solve_nonlinear(self, params, unknowns, resids):
"""
Evaluates the equation
y1 = z1**2 + z2 + x1 - 0.2*y2
"""
z1_d1 = params['z']
z2_d1 = params['z2_d1']
x1_d1 = params['x1_d1']
y2_d1 = params['y2_d1']
z1 = params['z1']
x1 = params['x2']
z2 = params['z2']
y2 = params['y2']
unknowns['obj1'] = (z1 - z1_d1) ** 2 + (x1 - x1_d1) ** 2 + (z2 - z2_d1) ** 2 + 0.2 * (y2 - y2_d1)
class SubOpt1(Component):
def __init__(self):
"""
Sobopt of discipline1
"""
super(SubOpt1, self).__init__()
self.add_param('S1px', IndepVarComp('x1_d1', 1.0), promotes=['x1_d1'])
self.add_param('S1pz', IndepVarComp('z1_d1', 5.0), promotes=['z1_d1'])
self.add_param('S1pz', IndepVarComp('z2_d1', 5.0), promotes=['z2_d1'])
self.add_param('S1py2', IndepVarComp('y2_d1', 2.0), promotes=['y2_d1'])
# Add Problem
from openmdao.api import Problem
self.problem = prob = Problem()
group = prob.root = Group()
# add Component:
group.add('Discipline', Discipline1,
promotes=['x1', 'z1', 'x2', 'y2', 'x1_d1', 'z1_d1', 'x2_d2', 'y2_d2', 'obj1'])
# Add Cons
group.add('con', ExecComp('con = z1_d1**2 + x1_d1 + z2_d1 - 0.2 * y2_d1'),
promotes=['con', 'z1_d1', 'x1_d1', 'z2_d1', 'y2_d1'])
# Add Solver
prob.driver = ScipyOptimizer()
prob.driver.options['optimizer'] = 'SLSQP'
prob.driver.options['tol'] = 1.0e-8
# Add desvar
prob.driver.add_desvar('x1_d1', lower=0.0, upper=10.0)
prob.driver.add_desvar('z1_d1', lower=-10.0, upper=10.0)
prob.driver.add_desvar('z2_d1', lower=0.0, upper=10.0)
prob.driver.add_desvar('y2_d1')
# Add obj and cons
prob.driver.add_objective('obj1')
prob.driver.add_constraint('con', lower=3.16)
prob.setup()
def solve_nonlinear(self, params=None, unknowns=None, resids=None, metadata=None):
self.problem.run()
unknowns['obj1'] = self.problem['obj1']
class Discipline2(Component):
"""Component containing Discipline 1."""
def __init__(self):
super(Discipline2, self).__init__()
self.add_param('z1_d2', val=0.0)
self.add_param('z2_d2', val=0.)
self.add_param('y1_d2', val=1.0)
self.add_param('y2_d2', val=1.0)
self.add_param('z1', val=1.0)
self.add_param('y1', val=1.0)
self.add_param('z2', val=1.0)
self.add_param('y2', val=1.0)
# add objs
self.add_param('obj2', val=1.0)
def solve_nonlinear(self, params, unknowns, resids):
"""
Evaluates the equation
y1 = z1**2 + z2 + x1 - 0.2*y2
"""
z1_d2 = params['z1_d2']
z2_d2 = params['z2_d2']
y1_d2 = params['y1_d2']
y2_d2 = params['y2_d2']
z1 = params['z1']
y1 = params['y2']
z2 = params['z2']
y2 = params['y2']
unknowns['obj2'] = (y2 - y2_d2) ** 2 + (y1 - y1_d2) ** 2 + (z1 - z1_d2) ** 2 + (z2 - z2_d2) ** 2
class SubOpt2(Component):
def __init__(self):
"""
Subopt of discipline2
"""
super(SubOpt2, self).__init__()
# Add Desvar
self.add_param('S2pz', IndepVarComp('z1_d2', 5.0), promotes=['z1_d2'])
self.add_param('S2pz', IndepVarComp('z2_d2', 5.0), promotes=['z2_d2'])
self.add_param('S2py1', IndepVarComp('y1_d2', 2.0), promotes=['y1_d2'])
self.add_param('S2py2', IndepVarComp('y2_d2', 5.0), promotes=['y2_d2'])
# Add problem
from openmdao.api import Problem
self.problem = prob = Problem()
group = prob.root = Group()
# Add Component:
group.add('Discipline2', Discipline2,
promotes=['obj2', 'y2', 'y2_d2', 'y1', 'y1_d2', 'z1', 'z1_d2', 'z2', 'z2_d2'])
# Add cons:
group.add('con2', ExecComp('con = y1_d2 ** 0.5 + z1_d2 + z2_d2'),
promotes=['con', 'y1_d2', 'z1_d2', 'z2_d2'])
# Add solver:
prob.driver = ScipyOptimizer()
prob.driver.options['optimizer'] = 'SLSQP'
prob.driver.options['tol'] = 1.0e-8
# Add desvar
prob.driver.add_desvar('y1_d2')
prob.driver.add_desvar('y2_d2')
prob.driver.add_desvar('z1_d2', lower=-10, upper=10)
prob.driver.add_desvar('z2_d2', lower=0.0, upper=10.0)
# Add ovj and cons
prob.driver.add_objective('obj2')
prob.driver.add_constraint('con2', upper=24)
prob.setup()
def solve_nonlinear(self, params=None, unknowns=None, resids=None, metadata=None):
self.problem.run()
class System_Opt(Group):
"""
Group containing the Sellar MDA. This version uses the disciplines
with derivatives."""
def __init__(self):
super(System_Opt, self).__init__()
self.add('px', IndepVarComp('x1', 1.0), promotes=['x1'])
self.add('pz1', IndepVarComp('z1', 5.0), promotes=['z1'])
self.add('pz2', IndepVarComp('z2', 5.0), promotes=['z2'])
self.add('py1', IndepVarComp('y1', 2.0), promotes=['y1'])
self.add('py2', IndepVarComp('y2', 2.0), promotes=['y2'])
self.add('obj_cmp', ExecComp('obj = x1**2 + z2 + y1 + eye(-y2)',
z2=0.0, x1=0.0, y1=0.0, y2=0.0),
promotes=['obj', 'z2', 'x1', 'y1', 'y2'])
self.add('SubOpt1', SubOpt1, promotes=['z1_d1', 'x1_d1', 'z2_d1', 'y2_d1', 'x1', 'z1', 'x2', 'y2'])
self.add('SubOpt2', SubOpt2, promotes=['y2_d2', 'y1_d2', 'z1_d2', 'z2_d2', 'y2', 'y1', 'z1', 'z2'])
self.add('con_cmp1',
ExecComp('con1 = (z1 - z1_d1)**2 + (x1 - x1_d1)**2 + (z2 - z2_d1)**2 + 0.2 * (y2 - y2_d1)'),
promotes=['con1', 'z1', 'z1_d1', 'x1', 'x1_d1', 'z2', 'z2_d1', 'y2', 'y2_d1'])
self.add('con_cmp2',
ExecComp('con2 = (y2 - y2_d2)**2 + (y1 - y1_d2)**2 + (z1 - z1_d2)**2 + (z2 - z2_d2)**2'),
promotes=['con2', 'y2', 'y2_d2', 'y1', 'y1_d2', 'z1', 'z1_d2', 'z2', 'z2_d2'])
if __name__ == '__main__':
epsilon = 1e-5
from openmdao.api import Problem, ScipyOptimizer
# Add problem
top = Problem()
top.root = System_Opt()
# Add solver
top.driver = ScipyOptimizer()
top.driver.options['optimizer'] = 'SLSQP'
top.driver.options['tol'] = 1.0e-8
# Add desvar
top.driver.add_desvar('x1', lower=0.0, upper=10.0)
top.driver.add_desvar('z1', lower=-10.0, upper=10.0)
top.driver.add_desvar('z2', lower=0.0, upper=10.0)
top.driver.add_desvar('y2')
top.driver.add_desvar('y1')
# Add obj and cons
top.driver.add_objective('obj')
top.driver.add_constraint('con1', upper=epsilon)
top.driver.add_constraint('con2', upper=epsilon)
top.setup()
# add init params of desvar
top['x1'] = 1.0
top['z1'] = 1.0
top['z2'] = 1.0
top['y2'] = 1.0
top['y1'] = 1.0
top.run()
The problem you are having is related to the following lines:
self.add('SubOpt1', SubOpt1, promotes=['z1_d1', 'x1_d1', 'z2_d1', 'y2_d1', 'x1', 'z1', 'x2', 'y2'])
self.add('SubOpt2', SubOpt2, promotes=['y2_d2', 'y1_d2', 'z1_d2', 'z2_d2', 'y2', 'y1', 'z1', 'z2'])
Note that here you passed the class into the add method, instead of an instance. You also did the same thing in SubOpt1 and SubOpt2
group.add('Discipline', Discipline1,
promotes=['x1', 'z1', 'x2', 'y2', 'x1_d1', 'z1_d1', 'x2_d2', 'y2_d2', 'obj1'])
# Add Cons
Instead, you need to pass instances into them as follows:
self.add('SubOpt1', SubOpt1(), promotes=['z1_d1', 'x1_d1', 'z2_d1', 'y2_d1', 'x1', 'z1', 'x2', 'y2'])
self.add('SubOpt2', SubOpt2(), promotes=['y2_d2', 'y1_d2', 'z1_d2', 'z2_d2', 'y2', 'y1', 'z1', 'z2'])
There are a few other minor typos in your script related to variable names, but the class vs instance issue is your main problem