Upgrading from 1.x

This guide takes how you did things in OpenMDAO Alpha and shows how to do them in the latest version of OpenMDAO.

Build a Model

Define an Explcit Component

class Paraboloid(Component):
    """
    Evaluates the equation f(x,y) = (x-3)^2 + xy + (y+4)^2 - 3.
    """

    def __init__(self):
        super(Paraboloid, self).__init__()

        self.add_param('x', val=0.0)
        self.add_param('y', val=0.0)

        self.add_output('f_xy', val=0.0)

    def solve_nonlinear(self, params, unknowns, resids):
        """
        f(x,y) = (x-3)^2 + xy + (y+4)^2 - 3

        Optimal solution (minimum): x = 6.6667; y = -7.3333
        """
        x = params['x']
        y = params['y']

        unknowns['f_xy'] = (x-3.0)**2 + x*y + (y+4.0)**2 - 3.0

    def linearize(self, params, unknowns, resids):
        """
        Jacobian for our paraboloid.
        """
        x = params['x']
        y = params['y']

        J = {}
        J['f_xy', 'x'] = 2.0*x - 6.0 + y
        J['f_xy', 'y'] = 2.0*y + 8.0 + x

        return J
class Paraboloid(ExplicitComponent):
    """
    Evaluates the equation f(x,y) = (x-3)^2 + xy + (y+4)^2 - 3.
    """

    def setup(self):
        self.add_input('x', val=0.0)
        self.add_input('y', val=0.0)

        self.add_output('f_xy', val=0.0)

        self.declare_partials('*', '*')

    def compute(self, inputs, outputs):
        """
        f(x,y) = (x-3)^2 + xy + (y+4)^2 - 3

        Optimal solution (minimum): x = 6.6667; y = -7.3333
        """
        x = inputs['x']
        y = inputs['y']

        outputs['f_xy'] = (x-3.0)**2 + x*y + (y+4.0)**2 - 3.0

    def compute_partials(self, inputs, partials):
        """
        Jacobian for our paraboloid.
        """
        x = inputs['x']
        y = inputs['y']

        partials['f_xy', 'x'] = 2.0*x - 6.0 + y
        partials['f_xy', 'y'] = 2.0*y + 8.0 + x

Define an Implicit Component

class ImplCompOneState(Component):
    """
    A Simple Implicit Component

    R(x,y) = 0.5y^2 + 2y + exp(-16y^2) + 2exp(-5y) - x

    Solution:
    x = 1.2278849186466743
    y = 0.3968459
    """

    def setup(self):
        self.add_param('x', 1.2278849186466743)
        self.add_state('y', val=1.0)

    def apply_nonlinear(self, params, unknowns, resids):
        """
        Don't solve; just calculate the residual.
        """
        x = params['x']
        y = unknowns['y']

        resids['y'] = 0.5*y*y + 2.0*y + exp(-16.0*y*y) + 2.0*exp(-5.0*y) - x

    def linearize(self, params, unknowns, resids):
        """
        Analytical derivatives.
        """
        y = unknowns['y']

        J = {}

        # State equation
        J[('y', 'x')] = -1.0
        J[('y', 'y')] = y + 2.0 - 32.0*y*exp(-16.0*y*y) - 10.0*exp(-5.0*y)

        return J
class ImplCompOneState(ImplicitComponent):
    """
    A Simple Implicit Component

    R(x,y) = 0.5y^2 + 2y + exp(-16y^2) + 2exp(-5y) - x

    Solution:
    x = 1.2278849186466743
    y = 0.3968459
    """

    def setup(self):
        self.add_input('x', 1.2278849186466743)
        self.add_output('y', val=1.0)

        self.declare_partials(of='*', wrt='*')

    def apply_nonlinear(self, inputs, outputs, resids):
        """
        Don't solve; just calculate the residual.
        """
        x = inputs['x']
        y = outputs['y']

        resids['y'] = 0.5*y*y + 2.0*y + exp(-16.0*y*y) + 2.0*exp(-5.0*y) - x

    def linearize(self, inputs, outputs, J):
        """
        Analytical derivatives.
        """
        y = outputs['y']

        # State equation
        J[('y', 'x')] = -1.0
        J[('y', 'y')] = y + 2.0 - 32.0*y*exp(-16.0*y*y) - 10.0*exp(-5.0*y)

Run a Model

Assemble and Run a Simple Model

prob = Problem()
root = prob.root = Group()

root.add('p1', IndepVarComp('x', 3.0))
root.add('p2', IndepVarComp('y', -4.0))
root.add('comp', Paraboloid())

root.connect('p1.x', 'comp.x')
root.connect('p2.y', 'comp.y')

prob.setup()
prob.run()
from openmdao.api import Problem, Group, IndepVarComp
from openmdao.test_suite.components.paraboloid import Paraboloid

prob = Problem()
model = prob.model = Group()

model.add_subsystem('p1', IndepVarComp('x', 3.0))
model.add_subsystem('p2', IndepVarComp('y', -4.0))
model.add_subsystem('comp', Paraboloid())

model.connect('p1.x', 'comp.x')
model.connect('p2.y', 'comp.y')

prob.setup()
prob.run_model()

Run a Driver

prob.run()
prob.run_driver()

Run a Model without Running the Driver

prob.run_once()
prob.run_model()

Check a Model

Specify Finite Difference for all Component Derivatives

def __init__(self):
    super(SellarDis1, self).__init__()

    # Global Design Variable
    self.add_param('z', val=np.zeros(2))

    # Local Design Variable
    self.add_param('x', val=0.)

    # Coupling parameter
    self.add_param('y2', val=1.0)

    # Coupling output
    self.add_output('y1', val=1.0)

    # Finite difference all partials.
    self.deriv_options['type'] = 'fd'
    def setup(self):

        # Global Design Variable
        self.add_input('z', val=np.zeros(2))

        # Local Design Variable
        self.add_input('x', val=0.)

        # Coupling parameter
        self.add_input('y2', val=1.0)

        # Coupling output
        self.add_output('y1', val=1.0)

        # Finite difference all partials.
        self.declare_partials('*', '*', method='fd')

Specify FD Form and Stepsize on Specific Derivatives

def __init__(self):
    super(PartialComp, self).__init__()

    self.add_param('x', shape=(4,), step_size=1e-4, form='backward')
    self.add_param('y', shape=(2,), step_size=1e-6, form='central')
    self.add_param('y2', shape=(2,), step_size=1e-6, form='central')
    self.add_output('f', shape=(2,))
def setup(self):
    self.add_input('x', shape=(4,))
    self.add_input('y', shape=(2,))
    self.add_input('y2', shape=(2,))
    self.add_output('f', shape=(2,))

    self.declare_partials('f', 'y*', method='fd', form='backward', step=1e-6)
    self.declare_partials('f', 'x', method='fd', form='central', step=1e-4)

Check Partial Derivatives on All Components

data = prob.check_partials()
data = prob.check_partials()

Suppress Output While Checking Partial Derivatives

data = prob.check_partials(out_stream=None)
data = prob.check_partials(suppress_output=True)

Check Partial Derivatives with Complex Step

  prob.root.deriv_options['check_type'] = 'cs'

  prob.setup()
  prob.run()

  prob.check_partials()
opts = {'method' : 'cs'}

prob.setup(force_alloc_complex=True)
prob.run_model()

prob.check_partials(global_options=opts)

Change Derivative Behavior

Force Group or Model to use Finite Difference

model.deriv_options['type'] = 'fd'
model.approx_totals()

Force Group or Model to use Finite Difference with Specific Options

model.deriv_options['type'] = 'fd'
model.deriv_options['step_size'] = '1e-7'
model.deriv_options['form'] = 'central'
model.deriv_options['step_calc'] = 'relative'
model.approx_totals(method='fd', step=1e-7, form='central', step_calc='rel')

Add Design Variables

Add a Design Variable to a Model

prob = Problem()
prob.root = SellarDerivatives()

prob.add_desvar('z')
prob = Problem()
prob.model = model = SellarDerivatives()

model.add_design_var('z')

Add a Design Variable with Scale and Offset that Maps [3, 5] to [0, 1]

prob = Problem()
prob.root = SellarDerivatives()

prob.add_desvar('z', scaler=0.5, adder=-3.0)
prob = Problem()
prob.model = model = SellarDerivatives()

model.add_design_var('z', ref=5.0, ref0=3.0)

Set Solvers

Setup a Problem Using the PetscVector

prob.setup(impl=PetscImpl)
prob.setup(vector_class=PETScVector)

Specify Newton as a Nonlinear Solver in a Group

model.nl_solver = Newton()
from openmdao.api import Problem, Group, IndepVarComp, NewtonSolver, LinearBlockGS, ExecComp

Specify Block Gauss Seidel as a Nonlinear Solver in a Group

model.nl_solver = NLGaussSeidel()
from openmdao.api import Problem, Group, IndepVarComp, ExecComp, NonlinearBlockGS

Specify Scipy GMRES as a Linear Solver in a Group

model.ln_solver = ScipyGMRES()
from openmdao.api import Problem, Group, IndepVarComp, ScipyIterativeSolver, \

Specify Linear Block Gauss Seidel as a Linear Solver in a Group

model.ln_solver = LinearGaussSeidel()
from openmdao.api import Problem, Group, IndepVarComp, ExecComp, LinearBlockGS, NonlinearBlockGS