Search code examples
openmdao

Is there any way to update the sparse partial indices on the fly


Let's say I have this explicit component with sparse partial declaration. Is there any way that i can change the partial indices after I setup the problem and start the optimization. The size of the partials will not change (say it is always (4,1)) but the locations (rows/columns) will change. Is this possible maybe there is a trick?

import numpy as np
import openmdao.api as om
class SparsePartialComp(om.ExplicitComponent):
    def setup(self):
        self.add_input('x', shape=(4,))
        self.add_output('f', shape=(2,))

        self.declare_partials(of='f', wrt='x',
                              rows=[0, 1, 1, 1],
                              cols=[0, 1, 2, 3])

    def compute_partials(self, inputs, partials):
        # Corresponds to the [(0,0), (1,1), (1,2), (1,3)] entries.
        partials['f', 'x'] = [1., 2., 3., 4.]

model = om.Group()
comp = om.IndepVarComp()
comp.add_output('x', np.ones(4))

model.add_subsystem('input', comp)
model.add_subsystem('example', SparsePartialComp())

model.connect('input.x', 'example.x')

problem = om.Problem(model=model)
problem.setup()
problem.run_model()
totals = problem.compute_totals(['example.f'], ['input.x'])

print(totals['example.f', 'input.x'])

Solution

  • As over OpenMDAO V2.8, changing the sparsity pattern on the fly is not allowed. You have to figure out all of the entries that could possibly be non-zero an declare all of them.

    Its possible that we'll lift this restriction in the future, though doing so is not on the roadmap for the next year. Even if we did add it though, there would be some significant overhead for doing this kind of on-the-fly switching and it would not be advisable to do it often within an execution. The setup overhead would swamp everything else, unless the sparsity savings were huge --- 4x1 is NOT huge :)