Upgrading from OpenMDAO 2.10 to OpenMDAO 3¶
In the OpenMDAO 3.0 release, a few changes were made to the API. In addition, we removed all deprecation warnings and fully deprecated the old behavior for all API changes that were made over the lifespan of OpenMDAO 2.x. The changes are all summarized here.
Building Component Models¶
Declare a Component with distributed variables¶
class DistribComp(ExplicitComponent):
def __init__(self, size):
super().__init__()
self.distributed = True
class DistribComp(om.ExplicitComponent):
"""Simple Distributed Component."""
def initialize(self):
self.options['distributed'] = True
Declare a variable that is explicitly unitless¶
prob.model.add_subsystem('tgt', om.ExecComp('y = 3 * x', x={'units': 'unitless'}))
prob.model.add_subsystem('tgt', om.ExecComp('y = 3 * x', x={'units': None}))
Add a subsystem to a Group¶
indeps = prob.model.add('indeps', om.IndepVarComp())
prob.model.add_subsystem('parab', Paraboloid(), promotes_inputs=['x', 'y'])
Add a linear or nonlinear solver to a Group¶
self.nl_solver = om.NewtonSolver()
self.ln_solver = om.DirectSolver()
self.nonlinear_solver = om.NewtonSolver()
self.linear_solver = om.DirectSolver()
Declare an option with an explicit type¶
def initialize(self):
"""
Declare options.
"""
self.options.declare('vec_size', type_=int, default=1,
desc='The number of points at which the vector magnitude is computed')
def initialize(self):
"""
Declare options.
"""
self.options.declare('vec_size', types=int, default=1,
desc='The number of points at which the vector magnitude is computed')
Component Library¶
Create an interpolating component using Akima spline with uniform grid¶
ycp = np.array([5.0, 12.0, 14.0, 16.0, 21.0, 29.0])
ncp = len(ycp)
n = 11
prob = om.Problem()
comp = om.AkimaSplineComp(num_control_points=ncp, num_points=n,
name='chord')
prob.model.add_subsystem('comp1', comp)
prob.setup()
prob['akima.chord:y_cp'] = ycp.reshape((1, ncp))
prob.run_model()
ycp = np.array([5.0, 12.0, 14.0, 16.0, 21.0, 29.0])
ncp = len(ycp)
n = 11
prob = om.Problem()
akima_option = {'delta_x': 0.1}
comp = om.SplineComp(method='akima', num_cp=ncp, x_interp_val=np.linspace(0.0, 1.0, n),
interp_options=akima_option)
prob.model.add_subsystem('comp1', comp)
comp.add_spline(y_cp_name='chord_cp', y_interp_name='chord', y_cp_val=ycp)
prob.setup()
prob.run_model()
Create an interpolating component using Akima spline with custom grid¶
xcp = np.array([1.0, 2.0, 4.0, 6.0, 10.0, 12.0])
ycp = np.array([5.0, 12.0, 14.0, 16.0, 21.0, 29.0])
ncp = len(xcp)
n = 50
x = np.linspace(1.0, 12.0, n)
prob = om.Problem()
comp = om.AkimaSplineComp(num_control_points=ncp, num_points=n,
name='chord', input_x=True,
input_xcp=True)
prob.model.add_subsystem('akima', comp)
prob.setup(force_alloc_complex=True)
prob['akima.chord:x_cp'] = xcp
prob['akima.chord:y_cp'] = ycp.reshape((1, ncp))
prob['akima.chord:x'] = x
prob.run_model()
xcp = np.array([1.0, 2.0, 4.0, 6.0, 10.0, 12.0])
ycp = np.array([5.0, 12.0, 14.0, 16.0, 21.0, 29.0])
n = 50
x = np.linspace(1.0, 12.0, n)
prob = om.Problem()
akima_option = {'delta_x': 0.1}
comp = om.SplineComp(method='akima', x_cp_val=xcp, x_interp_val=x,
interp_options=akima_option)
prob.model.add_subsystem('akima1', comp)
comp.add_spline(y_cp_name='ycp', y_interp_name='y_val', y_cp_val=ycp)
prob.setup(force_alloc_complex=True)
prob.run_model()
Create an interpolating component using Bsplines¶
prob = om.Problem()
model = prob.model
n_cp = 5
n_point = 10
t = np.linspace(0, 0.5*np.pi, n_cp)
x = np.empty((2, n_cp))
x[0, :] = np.sin(t)
x[1, :] = 2.0*np.sin(t)
comp = om.BsplinesComp(num_control_points=n_cp,
num_points=n_point,
bspline_order=4,
distribution='sine',
vec_size=2,
in_name='h_cp',
out_name='h')
model.add_subsystem('interp', comp)
prob.setup()
prob.run_model()
from openmdao.utils.spline_distributions import sine_distribution
prob = om.Problem()
model = prob.model
n_cp = 5
n_point = 10
t = np.linspace(0, 0.5 * np.pi, n_cp)
x = np.empty((2, n_cp))
x[0, :] = np.sin(t)
x[1, :] = 2.0 * np.sin(t)
# In 2.x, the BsplinesComp had a built-in sinusoidal distribution.
t_sin = sine_distribution(n_point) * np.pi * 0.5
bspline_options = {'order': 4}
comp = om.SplineComp(method='bsplines',
x_interp_val=t_sin,
num_cp=n_cp,
vec_size=2,
interp_options=bspline_options)
prob.model.add_subsystem('interp', comp)
comp.add_spline(y_cp_name='h_cp', y_interp_name='h', y_cp_val=x, y_units='km')
prob.setup()
prob.run_model()
Create an ExecComp with diagonal partials¶
model.add_subsystem('comp', ExecComp('y=3.0*x + 2.5',
vectorize=True,
x=np.ones(5), y=np.ones(5)))
model.add_subsystem('comp', om.ExecComp('y=3.0*x + 2.5',
has_diag_partials=True,
x=np.ones(5), y=np.ones(5)))
Create an IndepVarComp with multiple outputs¶
comp = om.IndepVarComp((
('indep_var_1', 1.0, {'lower': 0, 'upper': 10}),
('indep_var_2', 2.0, {'lower': 1., 'upper': 20}),
))
comp = om.IndepVarComp()
comp.add_output('indep_var_1', val=1.0)
comp.add_output('indep_var_2', val=2.0)
Create an ExternalCode¶
class ParaboloidExternalCodeCompDerivs(om.ExternalCode):
class ParaboloidExternalCodeCompDerivs(om.ExternalCodeComp):
Create a KSComponent¶
model.add_subsystem('ks', om.KSComponent(width=2))
model.add_subsystem('ks', om.KSComp(width=2))
Create a MetaModel¶
sin_mm = om.MetaModel()
sin_mm = om.MetaModelUnStructuredComp()
Create a MetaModelUnstructured¶
sin_mm = om.MetaModelUnstructured()
sin_mm = om.MetaModelUnStructuredComp()
Create a MetaModelStructured¶
interp = om.MetaModelStructured(method='scipy_cubic', vec_size=2)
interp = om.MetaModelStructuredComp(method='scipy_cubic', vec_size=2)
Create a MultiFiMetaModel¶
mm = om.MultiFiMetaModel(nfi=2)
mm = om.MultiFiMetaModelUnStructuredComp(nfi=2)
Create a MultiFiMetaModelUnStructured¶
mm = om.MultiFiMetaModelUnStructured(nfi=2)
mm = om.MultiFiMetaModelUnStructuredComp(nfi=2)
Add a FloatKrigingSurrogate to a MetaModelStructuredComp¶
sin_mm.add_output('f_x', 0., surrogate=om.FloatKrigingSurrogate())
sin_mm.add_output('f_x', 0., surrogate=om.KrigingSurrogate())
Specify a default surrogate model for MetaModelStructuredComp¶
trig = om.MetaModelUnStructuredComp(vec_size=size)
trig.default_surrogate = om.KrigingSurrogate()
trig = om.MetaModelUnStructuredComp(vec_size=size, default_surrogate=om.KrigingSurrogate())
Solvers¶
Declare a NewtonSolver with solve_subsystems set to False¶
newton = model.nonlinear_solver = om.NewtonSolver()
newton = model.nonlinear_solver = om.NewtonSolver(solve_subsystems=False)
Control how a solver handles an error raised in a subsolver¶
newton = model.nonlinear_solver = NewtonSolver()
newton.options['maxiter'] = 1
newton.options['err_on_maxiter'] = True
newton = model.nonlinear_solver = om.NewtonSolver(solve_subsystems=False)
newton.options['maxiter'] = 1
newton.options['err_on_non_converge'] = True
Declare a BroydenSolver with the BoundsEnforceLS line search¶
model.circuit.nonlinear_solver = om.BroydenSolver()
model.circuit.nonlinear_solver.linesearch = om.BoundsEnforceLS()
model.circuit.nonlinear_solver = om.BroydenSolver()
Declare a NewtonSolver with the BoundsEnforceLS line search¶
newton = model.nonlinear_solver = om.NewtonSolver(solve_subsystems=False)
newton.linesearch = om.BoundsEnforceLS()
newton = model.nonlinear_solver = om.NewtonSolver(solve_subsystems=False)
Add a preconditioner to PETScKrylov¶
model.linear_solver = om.PETScKrylov()
model.linear_solver.preconditioner = om.LinearBlockGS()
model.linear_solver = om.PETScKrylov()
model.linear_solver.precon = om.LinearBlockGS()
Add a preconditioner to ScipyKrylov¶
model.linear_solver.preconditioner = om.LinearBlockGS()
model.linear_solver.precon = om.LinearBlockGS()
Add a ArmijoGoldsteinLS to a NewtonSolver¶
top.model.nonlinear_solver = om.NewtonSolver(solve_subsystems=False)
top.model.nonlinear_solver.options['maxiter'] = 10
top.model.linear_solver = om.ScipyKrylov()
ls = top.model.nonlinear_solver.line_search = om.ArmijoGoldsteinLS(bound_enforcement='vector')
top.model.nonlinear_solver = om.NewtonSolver(solve_subsystems=False)
top.model.nonlinear_solver.options['maxiter'] = 10
top.model.linear_solver = om.ScipyKrylov()
ls = top.model.nonlinear_solver.linesearch = om.ArmijoGoldsteinLS(bound_enforcement='vector')
Create a NonLinearRunOnce¶
model.nonlinear_solver = om.NonLinearRunOnce()
model.nonlinear_solver = om.NonlinearRunOnce()
Create a PetscKSP¶
model.linear_solver = om.PetscKSP()
model.linear_solver = om.PETScKrylov()
Create a ScipyIterativeSolver¶
model.linear_solver = om.ScipyIterativeSolver()
model.linear_solver = om.ScipyKrylov()
Drivers¶
Activate dynamic coloring on a Driver¶
p.driver.options['dynamic_simul_derivs'] = True
p.driver.declare_coloring()
Add a ScipyOptimizer to a Problem¶
prob.driver = om.ScipyOptimizer()
prob.driver = om.ScipyOptimizeDriver()
Working with Derivatives¶
Use a pre-computed coloring on a model¶
p.driver.set_simul_deriv_color()
p.driver.use_fixed_coloring()
Case Reading¶
Query the iteration coordinate for a case¶
cr = om.CaseReader(self.filename)
for i, c in enumerate(cr.list_cases()):
case = cr.get_case(c)
coord = case.iteration_coordinate
cr = om.CaseReader(self.filename)
for i, c in enumerate(cr.list_cases(out_stream=None)):
case = cr.get_case(c)
coord = case.name