Basic Recording Example#

Recording Terminology#

  • Case: A Case stores a snapshot of all the variable values, metadata, and options of a model, or a sub-set of a model, at a particular point in time

  • Case Recorder: An OpenMDAO module used to store a snapshot of a model before, during, or after execution in an SQL file.

  • Sources: The OpenMDAO object responsible for recording the case. Can be Problem, Driver or a specific System or Solver identified by pathname.

Basic Recording Example#

Below is a basic example of how to create a recorder, attach it to a Problem, save the information, and retrieve the data from the recorder. list_outputs is a quick way to show all of your outputs and their values at the time the case was recorded, and should you need to isolate a single value OpenMDAO provides two ways to retrieve them. To view all the design variables, constraints, and objectives, you can use their methods like the example below.

from openmdao.test_suite.components.sellar_feature import SellarMDAWithUnits
import numpy as np
import openmdao.api as om

# build the model
prob = om.Problem(model=SellarMDAWithUnits())

model = prob.model
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)

# setup the optimization
driver = prob.driver = om.ScipyOptimizeDriver(optimizer='SLSQP', tol=1e-9, disp=False)

# Create a recorder variable
recorder = om.SqliteRecorder('cases.sql')
# Attach a recorder to the problem
prob.add_recorder(recorder)

prob.setup()
prob.set_solver_print(2)
prob.run_driver()
prob.record("after_run_driver")

# Instantiate your CaseReader
cr = om.CaseReader(prob.get_outputs_dir() / "cases.sql")
# Isolate "problem" as your source
driver_cases = cr.list_cases('problem', out_stream=None)
# Get the first case from the recorder
case = cr.get_case('after_run_driver')

# These options will give outputs as the model sees them
# Gets value but will not convert units
const = case['con1']
print(const)

# get_val can convert your result's units if desired
const_K = case.get_val("con1", units='K')

print(const_K)
=====
cycle
=====
NL: NLBGS 1 ; 29.0742299 1
NL: NLBGS 2 ; 2.26505979 0.0779060975
NL: NLBGS 3 ; 0.0438762115 0.00150911001
NL: NLBGS 4 ; 0.000867730413 2.98453446e-05
NL: NLBGS 5 ; 1.715381e-05 5.90000492e-07
NL: NLBGS 6 ; 3.39109478e-07 1.16635756e-08
NL: NLBGS 7 ; 6.70377103e-09 2.30574328e-10
NL: NLBGS 8 ; 1.32523072e-10 4.55809395e-12
NL: NLBGS Converged
=====
cycle
=====
NL: NLBGS 1 ; 2.62038164e-12 1
NL: NLBGS Converged
=====
cycle
=====
NL: NLBGS 1 ; 19.1706591 1
NL: NLBGS 2 ; 1.13589624 0.0592518093
NL: NLBGS 3 ; 0.0406301437 0.00211939211
NL: NLBGS 4 ; 0.00140619452 7.33513916e-05
NL: NLBGS 5 ; 4.87225696e-05 2.54151771e-06
NL: NLBGS 6 ; 1.68809957e-06 8.80564178e-08
NL: NLBGS 7 ; 5.84879659e-08 3.05091054e-09
NL: NLBGS 8 ; 2.0264451e-09 1.05705552e-10
NL: NLBGS 9 ; 7.02107155e-11 3.66240488e-12
NL: NLBGS Converged
=====
cycle
=====
NL: NLBGS 1 ; 5.26036063 1
NL: NLBGS 2 ; 0.514550635 0.0978166083
NL: NLBGS 3 ; 0.0258623712 0.00491646354
NL: NLBGS 4 ; 0.00126421196 0.000240328003
NL: NLBGS 5 ; 6.18806612e-05 1.17635777e-05
NL: NLBGS 6 ; 3.02873598e-06 5.75765845e-07
NL: NLBGS 7 ; 1.48241325e-07 2.81808293e-08
NL: NLBGS 8 ; 7.25566292e-09 1.37930903e-09
NL: NLBGS 9 ; 3.55128146e-10 6.75102281e-11
NL: NLBGS Converged
=====
cycle
=====
NL: NLBGS 1 ; 1.07485557 1
NL: NLBGS 2 ; 0.0990937832 0.0921926498
NL: NLBGS 3 ; 0.00548653522 0.00510443949
NL: NLBGS 4 ; 0.000301840404 0.0002808195
NL: NLBGS 5 ; 1.66114932e-05 1.54546282e-05
NL: NLBGS 6 ; 9.14179753e-07 8.50514039e-07
NL: NLBGS 7 ; 5.03100777e-08 4.68063608e-08
NL: NLBGS 8 ; 2.76871581e-09 2.57589567e-09
NL: NLBGS 9 ; 1.52370833e-10 1.41759355e-10
NL: NLBGS 10 ; 8.38562892e-12 7.80163321e-12
NL: NLBGS Converged
=====
cycle
=====
NL: NLBGS 1 ; 0.158851234 1
NL: NLBGS 2 ; 0.0153545659 0.0966600355
NL: NLBGS 3 ; 0.000862519808 0.00542973314
NL: NLBGS 4 ; 4.84015908e-05 0.000304697607
NL: NLBGS 5 ; 2.71628246e-06 1.70995364e-05
NL: NLBGS 6 ; 1.52436453e-07 9.59617683e-07
NL: NLBGS 7 ; 8.55466153e-09 5.38532898e-08
NL: NLBGS 8 ; 4.80083341e-10 3.02221978e-09
NL: NLBGS 9 ; 2.69420789e-11 1.69605726e-10
NL: NLBGS Converged
=====
cycle
=====
NL: NLBGS 1 ; 0.0172187064 1
NL: NLBGS 2 ; 0.00168376512 0.0977869697
NL: NLBGS 3 ; 9.47059834e-05 0.00550017993
NL: NLBGS 4 ; 5.32629053e-06 0.00030933163
NL: NLBGS 5 ; 2.99553923e-07 1.73970051e-05
NL: NLBGS 6 ; 1.68470947e-08 9.78418138e-07
NL: NLBGS 7 ; 9.47490619e-10 5.50268177e-08
NL: NLBGS 8 ; 5.32871939e-11 3.0947269e-09
NL: NLBGS Converged
=====
cycle
=====
NL: NLBGS 1 ; 0.00175633487 1
NL: NLBGS 2 ; 0.000171891789 0.0978695987
NL: NLBGS 3 ; 9.66953305e-06 0.00550551789
NL: NLBGS 4 ; 5.43939907e-07 0.000309701707
NL: NLBGS 5 ; 3.05982523e-08 1.74216505e-05
NL: NLBGS 6 ; 1.72124338e-09 9.80020045e-07
NL: NLBGS 7 ; 9.68247166e-11 5.51288472e-08
NL: NLBGS Converged
=====
cycle
=====
NL: NLBGS 1 ; 0.000177747678 1
NL: NLBGS 2 ; 1.73975931e-05 0.097878033
NL: NLBGS 3 ; 9.78689685e-07 0.00550606173
NL: NLBGS 4 ; 5.50554542e-08 0.000309739373
NL: NLBGS 5 ; 3.09710316e-09 1.74241554e-05
NL: NLBGS 6 ; 1.74224984e-10 9.80181494e-07
NL: NLBGS 7 ; 9.80082451e-12 5.51389736e-08
NL: NLBGS Converged
=====
cycle
=====
NL: NLBGS 1 ; 1.79815153e-05 1
NL: NLBGS 2 ; 1.76001069e-06 0.0978788865
NL: NLBGS 3 ; 9.90083225e-08 0.00550611675
NL: NLBGS 4 ; 5.56965192e-09 0.000309743191
NL: NLBGS 5 ; 3.13317193e-10 1.74244043e-05
NL: NLBGS 6 ; 1.7625223e-11 9.80185634e-07
NL: NLBGS Converged
=====
cycle
=====
NL: NLBGS 1 ; 1.81860686e-06 1
NL: NLBGS 2 ; 1.78003029e-07 0.097878785
NL: NLBGS 3 ; 1.00134526e-08 0.00550611178
NL: NLBGS 4 ; 5.63301034e-10 0.00030974316
NL: NLBGS 5 ; 3.1688238e-11 1.74244576e-05
NL: NLBGS Converged
=====
cycle
=====
NL: NLBGS 1 ; 1.83861089e-07 1
NL: NLBGS 2 ; 1.79965059e-08 0.0978809926
NL: NLBGS 3 ; 1.01238247e-09 0.00550623558
NL: NLBGS 4 ; 5.69505864e-11 0.000309747901
NL: NLBGS Converged
=====
cycle
=====
NL: NLBGS 1 ; 1.86043395e-08 1
NL: NLBGS 2 ; 1.82084181e-09 0.0978718871
NL: NLBGS 3 ; 1.02430388e-10 0.00550572561
NL: NLBGS 4 ; 5.76232489e-12 0.000309730151
NL: NLBGS Converged
=====
cycle
=====
NL: NLBGS 1 ; 1.87836585e-09 1
NL: NLBGS 2 ; 1.83846404e-10 0.0978757168
NL: NLBGS 3 ; 1.03422703e-11 0.00550599355
NL: NLBGS Converged
[-1.66727521e-10]
[273.15]
# list_outputs will list your model's outputs and return a list of them too
print(case.list_outputs())
5 Explicit Output(s) in 'model'

varname   val                prom_name
--------  -----------------  ---------
cycle
  d1
    y1    [3.16]             y1       
  d2
    y2    [3.75527777]       y2       
obj_cmp
  obj     [3.18339395]       obj      
con_cmp1
  con1    [-1.66727521e-10]  con1     
con_cmp2
  con2    [-20.24472223]     con2     


0 Implicit Output(s) in 'model'


[('con_cmp1.con1', {'val': array([-1.66727521e-10]), 'io': 'output', 'prom_name': 'con1'}), ('con_cmp2.con2', {'val': array([-20.24472223]), 'io': 'output', 'prom_name': 'con2'}), ('cycle.d1.y1', {'val': array([3.16]), 'io': 'output', 'prom_name': 'y1'}), ('cycle.d2.y2', {'val': array([3.75527777]), 'io': 'output', 'prom_name': 'y2'}), ('obj_cmp.obj', {'val': array([3.18339395]), 'io': 'output', 'prom_name': 'obj'})]
# This code below will find all the objectives, design variables, and constraints that the
# problem source contains
objectives = case.get_objectives()
print(objectives['obj'])

design_vars = case.get_design_vars()
print(design_vars['x'])

constraints = case.get_constraints()
print(constraints['con1'])
[3.18339395]
[1.52870779e-16]
[-1.66727521e-10]