Changing Model Settings After Setup

After Problem setup has been called, the entire model hierarchy has been instantiated and setup and configure have been called on all Groups and Components. However, you may still want to make some changes to your model configuration.

OpenMDAO allows you to do a limited number of things after the Problem setup has been called, but before you have called run_model or run_driver. These allowed actions include the following:

Here, we instantiate a hierarchy of Groups, and then change the solver to one that can solve this problem.

import openmdao.api as om


class ImplSimple(om.ImplicitComponent):

    def setup(self):
        self.add_input('a', val=1.)
        self.add_output('x', val=0.)

    def apply_nonlinear(self, inputs, outputs, residuals):
        residuals['x'] = np.exp(outputs['x']) - \
            inputs['a']**2 * outputs['x']**2

    def linearize(self, inputs, outputs, jacobian):
        jacobian['x', 'x'] = np.exp(outputs['x']) - \
            2 * inputs['a']**2 * outputs['x']
        jacobian['x', 'a'] = -2 * inputs['a'] * outputs['x']**2

class Sub(om.Group):

    def setup(self):
        self.add_subsystem('comp', ImplSimple())

        # This will not solve it
        self.nonlinear_solver = om.NonlinearBlockGS()

    def configure(self):
        # This will not solve it either.
        self.nonlinear_solver = om.NonlinearBlockGS()

class Super(om.Group):

    def setup(self):
        self.add_subsystem('sub', Sub())

top = om.Problem(model=Super())

top.setup()

# This will solve it.
top.model.sub.nonlinear_solver = om.NewtonSolver(solve_subsystems=False)
top.model.sub.linear_solver = om.ScipyKrylov()

print(isinstance(top.model.sub.nonlinear_solver, om.NewtonSolver))
print(isinstance(top.model.sub.linear_solver, om.ScipyKrylov))
True
True