Driver Recording#

A CaseRecorder is commonly attached to the problem’s Driver in order to gain insight into the convergence of the model as the driver finds a solution. By default, a recorder attached to a driver will record the design variables, constraints and objectives.

The driver recorder is capable of capturing any values from any part of the model, not just the design variables, constraints, and objectives.

/usr/share/miniconda/envs/test/lib/python3.11/site-packages/openmdao/utils/notebook_utils.py:120: OMDeprecationWarning:Argument `recording_options` is deprecated. Use `options_dict="recording_options" to remove this warning.

OptionDefaultAcceptable ValuesAcceptable TypesDescription
excludes[]N/A['list']Patterns for vars to exclude in recording (processed post-includes). Uses fnmatch wildcards
includes[]N/A['list']Patterns for variables to include in recording. Uses fnmatch wildcards
record_constraintsTrue[True, False]['bool']Set to True to record constraints at the driver level
record_derivativesFalse[True, False]['bool']Set to True to record derivatives at the driver level
record_desvarsTrue[True, False]['bool']Set to True to record design variables at the driver level
record_inputsTrue[True, False]['bool']Set to True to record inputs at the driver level
record_objectivesTrue[True, False]['bool']Set to True to record objectives at the driver level
record_outputsTrue[True, False]['bool']Set True to record outputs at the driver level.
record_residualsFalse[True, False]['bool']Set True to record residuals at the driver level.
record_responsesFalse[True, False]['bool']Set True to record constraints and objectives at the driver level

Note

Note that the excludes option takes precedence over the includes option.

Driver Recording Example#

In the example below, we first run a case while recording at the driver level. Then, we examine the objective, constraint, and design variable values at the last recorded case. Lastly, we print the full contents of the last case, including outputs from the problem that are not design variables, constraints, or objectives.

Specifically, y1 and y2 are some of those intermediate outputs that are recorded due to the use of:

driver.recording_options['includes'] = ['*']

import openmdao.api as om
from openmdao.test_suite.components.sellar_feature import SellarDerivatives

import numpy as np

model = SellarDerivatives()

model.nonlinear_solver = om.NonlinearBlockGS()
model.linear_solver = om.ScipyKrylov()

model.add_design_var('z', lower=np.array([-10.0, 0.0]),
                          upper=np.array([10.0, 10.0]))
model.add_design_var('x', lower=0.0, upper=10.0)
model.add_objective('obj')
model.add_constraint('con1', upper=0.0)
model.add_constraint('con2', upper=0.0)

driver = om.ScipyOptimizeDriver(optimizer='SLSQP', tol=1e-9)

driver.recording_options['includes'] = ['*']
driver.recording_options['record_objectives'] = True
driver.recording_options['record_constraints'] = True
driver.recording_options['record_desvars'] = True
driver.recording_options['record_inputs'] = True
driver.recording_options['record_outputs'] = True
driver.recording_options['record_residuals'] = True

driver.add_recorder(om.SqliteRecorder("cases.sql"))

prob = om.Problem(model, driver)
prob.setup()
prob.run_driver()
NL: NLBGS Converged in 8 iterations
NL: NLBGS Converged in 1 iterations
NL: NLBGS Converged in 9 iterations
NL: NLBGS Converged in 10 iterations
NL: NLBGS Converged in 10 iterations
NL: NLBGS Converged in 9 iterations
NL: NLBGS Converged in 6 iterations
Optimization terminated successfully    (Exit mode 0)
            Current function value: 3.183393951728078
            Iterations: 6
            Function evaluations: 6
            Gradient evaluations: 6
Optimization Complete
-----------------------------------
Problem: problem
Driver:  ScipyOptimizeDriver
  success     : True
  iterations  : 7
  runtime     : 4.2666E-02 s
  model_evals : 7
  model_time  : 8.9344E-03 s
  deriv_evals : 6
  deriv_time  : 1.8061E-02 s
  exit_status : SUCCESS
prob.cleanup()
cr = om.CaseReader(prob.get_outputs_dir() / "cases.sql")
driver_cases = cr.list_cases('driver')

driver
rank0:ScipyOptimize_SLSQP|0
rank0:ScipyOptimize_SLSQP|1
rank0:ScipyOptimize_SLSQP|2
rank0:ScipyOptimize_SLSQP|3
rank0:ScipyOptimize_SLSQP|4
rank0:ScipyOptimize_SLSQP|5
rank0:ScipyOptimize_SLSQP|6
last_case = cr.get_case(driver_cases[-1])
print(last_case)
driver rank0:ScipyOptimize_SLSQP|6 {'z': array([1.97763888, 0.        ]), 'x': array([3.56410563e-15]), 'con1': array([-8.86162255e-11]), 'con2': array([-20.24472223]), 'y1': array([3.16]), 'y2': array([3.75527777]), 'obj': array([3.18339395])}
last_case.get_objectives()
{'obj': array([3.18339395])}
last_case.get_design_vars()
{'z': array([1.97763888, 0.        ]), 'x': array([3.56410563e-15])}
last_case.get_constraints()
{'con1': array([-8.86162255e-11]), 'con2': array([-20.24472223])}
last_case.inputs['obj_cmp.x']
array([3.56410563e-15])
last_case.outputs['z']
array([1.97763888, 0.        ])
last_case.residuals['obj']
array([3.88031829e-11])
last_case['y1']
array([3.16])