Problem Recording#

You might also want to attach a recorder to the Problem itself. This allows you to record an arbitrary case at a point of your choosing. This feature can be useful if you only record a limited number of variables during the run but would like to see a more complete list of values after the run.

The options are a subset of those for driver recording.

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_abs_errorTrue[True, False]['bool']Set to True to record absolute error of model nonlinear solver
record_constraintsTrue[True, False]['bool']Set to True to record constraints at the problem level
record_derivativesFalse[True, False]['bool']Set to True to record derivatives for the problem level
record_desvarsTrue[True, False]['bool']Set to True to record design variables at the problem level
record_inputsFalse[True, False]['bool']Set True to record inputs at the problem level.
record_objectivesTrue[True, False]['bool']Set to True to record objectives at the problem level
record_outputsTrue[True, False]['bool']Set True to record outputs at the problem level.
record_rel_errorTrue[True, False]['bool']Set to True to record relative error of model nonlinear solver
record_residualsFalse[True, False]['bool']Set True to record residuals at the problem level.
record_responsesFalse[True, False]['bool']Set True to record constraints and objectives at the problem level.

Note

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

Problem Recording Example#

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)

prob = om.Problem(model, driver)

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

prob.recording_options['includes'] = []
prob.recording_options['record_objectives'] = True
prob.recording_options['record_constraints'] = True
prob.recording_options['record_desvars'] = True

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: problem2
Driver:  ScipyOptimizeDriver
  success     : True
  iterations  : 7
  runtime     : 3.5083E-02 s
  model_evals : 7
  model_time  : 8.7513E-03 s
  deriv_evals : 6
  deriv_time  : 2.1604E-02 s
  exit_status : SUCCESS
prob.record('final')
prob.cleanup()

cr = om.CaseReader(prob.get_outputs_dir() / "cases.sql")

# get list of cases recorded on problem
problem_cases = cr.list_cases('problem')

problem
final
# get list of output variables recorded on problem
cr.list_source_vars('problem')

inputsoutputsresiduals
z
x
con1
con2
obj
{'inputs': [], 'outputs': ['z', 'x', 'con1', 'con2', 'obj'], 'residuals': []}
# get the recorded case
case = cr.get_case('final')
case.get_objectives()
{'obj': array([3.18339395])}
case.get_design_vars()
{'z': array([1.97763888, 0.        ]), 'x': array([3.56410563e-15])}
case.get_constraints()
{'con1': array([-8.86162255e-11]), 'con2': array([-20.24472223])}