Computing Total Derivatives

Problem has a method, compute_totals, that allows you to compute the unscaled total derivative values for a model.

If the model approximated its Jacobian, the method uses an approximation method.

Problem.compute_totals(of=None, wrt=None, return_format='flat_dict', debug_print=False, driver_scaling=False)[source]

Compute derivatives of desired quantities with respect to desired inputs.

Parameters:
of : list of variable name strings or None

Variables whose derivatives will be computed. Default is None, which uses the driver’s objectives and constraints.

wrt : list of variable name strings or None

Variables with respect to which the derivatives will be computed. Default is None, which uses the driver’s desvars.

return_format : string

Format to return the derivatives. Can be either ‘dict’ or ‘flat_dict’. Default is a ‘flat_dict’, which returns them in a dictionary whose keys are tuples of form (of, wrt).

debug_print : bool

Set to True to print out some debug information during linear solve.

driver_scaling : bool

Set to True to scale derivative values by the quantities specified when the desvars and responses were added. Default if False, which is unscaled.

Returns:
derivs : object

Derivatives in form requested by ‘return_format’.

Usage

Here is a simple example of using compute_totals:

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()

totals = prob.compute_totals(of=['comp.f_xy'], wrt=['p1.x', 'p2.y'])
print(totals[('comp.f_xy','p1.x')][0][0])
-4.0
print(totals[('comp.f_xy','p2.y')][0][0])
3.0
totals = prob.compute_totals(of=['comp.f_xy'], wrt=['p1.x', 'p2.y'], return_format='dict')
print(totals['comp.f_xy']['p1.x'][0][0])
-4.0
print(totals['comp.f_xy']['p2.y'][0][0])
3.0

By default, compute_totals returns the derivatives unscaled, but you can also request that they be scaled by the driver scale values declared when the des_vars, objectives, or constraints are added:

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')

model.add_design_var('p1.x', 3.0, ref0=50.0)
model.add_design_var('p2.y', -4.0)
model.add_objective('comp.f_xy')

prob.setup()
prob.run_model()

totals = prob.compute_totals(of=['comp.f_xy'], wrt=['p1.x', 'p2.y'], driver_scaling=True)
print(totals[('comp.f_xy','p1.x')][0][0])
196.0
print(totals[('comp.f_xy','p2.y')][0][0])
3.0