System Recording#

If you need to focus on a smaller part of your model, it may be useful to attach a case recorder to a particular System. There are slightly different options when recording from these objects. System recording can only be used in serial running environments and cannot currently be used in parallel.

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
options_excludes[]N/A['list']User-defined metadata to exclude in recording
record_inputsTrue[True, False]['bool']Set to True to record inputs at the system level
record_outputsTrue[True, False]['bool']Set to True to record outputs at the system level
record_residualsTrue[True, False]['bool']Set to True to record residuals at the system level

Note

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

System Recording Example#

SellarDerivatives class definition

class SellarDerivatives(om.Group):
    """
    Group containing the Sellar MDA. This version uses the disciplines with derivatives.
    """

    def setup(self):
        self.add_subsystem('d1', SellarDis1withDerivatives(), promotes=['x', 'z', 'y1', 'y2'])
        self.add_subsystem('d2', SellarDis2withDerivatives(), promotes=['z', 'y1', 'y2'])

        self.add_subsystem('obj_cmp', om.ExecComp('obj = x**2 + z[1] + y1 + exp(-y2)', obj=0.0,
                                                  x=0.0, z=np.array([0.0, 0.0]), y1=0.0, y2=0.0),
                           promotes=['obj', 'x', 'z', 'y1', 'y2'])

        self.add_subsystem('con_cmp1', om.ExecComp('con1 = 3.16 - y1', con1=0.0, y1=0.0),
                           promotes=['con1', 'y1'])
        self.add_subsystem('con_cmp2', om.ExecComp('con2 = y2 - 24.0', con2=0.0, y2=0.0),
                           promotes=['con2', 'y2'])

        self.set_input_defaults('x', 1.0)
        self.set_input_defaults('z', np.array([5.0, 2.0]))

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

prob = om.Problem(name='system_recording', model=SellarDerivatives())
prob.setup()

recorder = om.SqliteRecorder("system_recording.sql")

obj_cmp = prob.model.obj_cmp
obj_cmp.add_recorder(recorder)
obj_cmp.recording_options['includes'] = ['*']
obj_cmp.recording_options['excludes'] = ['obj_cmp.x']

prob.model.nonlinear_solver = om.NonlinearBlockGS()
prob.model.nonlinear_solver.options['use_apply_nonlinear'] = True

prob.run_model()
[1790952397.538989] [runnervm8df0l:10607:0]        ib_iface.c:1269 UCX  ERROR mana_0: iface 0x55f65cc05300 failed to create UD QP TX wr:256 sge:6 inl:64 resp:0 RX wr:4096 sge:1 resp:0 failed: Operation not supported
[1790952397.539215] [runnervm8df0l:10607:0]      ucp_worker.c:1412 UCX  ERROR uct_iface_open(ud_verbs/mana_0:1) failed: Input/output error
NL: NLBGS Converged in 7 iterations
[runnervm8df0l:10607] pml_ucx.c:313  Error: Failed to create UCP worker
prob.cleanup()

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

system_cases = cr.list_cases('root.obj_cmp')

root.obj_cmp
rank0:root._solve_nonlinear|0|NonlinearBlockGS|0|obj_cmp._solve_nonlinear|0
rank0:root._solve_nonlinear|0|NonlinearBlockGS|1|obj_cmp._solve_nonlinear|1
rank0:root._solve_nonlinear|0|NonlinearBlockGS|2|obj_cmp._solve_nonlinear|2
rank0:root._solve_nonlinear|0|NonlinearBlockGS|3|obj_cmp._solve_nonlinear|3
rank0:root._solve_nonlinear|0|NonlinearBlockGS|4|obj_cmp._solve_nonlinear|4
rank0:root._solve_nonlinear|0|NonlinearBlockGS|5|obj_cmp._solve_nonlinear|5
rank0:root._solve_nonlinear|0|NonlinearBlockGS|6|obj_cmp._solve_nonlinear|6
case = cr.get_case(system_cases[0])

case.inputs
{'obj_cmp.y1': array([27.8]),
 'obj_cmp.y2': array([12.27257053]),
 'obj_cmp.z': array([5., 2.])}