def test_results_radau(self): gd = GridData(num_segments=3, transcription_order=[5, 3, 3], segment_ends=_segends, transcription='radau-ps') p = Problem(model=Group()) ivc = p.model.add_subsystem(name='ivc', subsys=IndepVarComp(), promotes_outputs=['*']) ivc.add_output('t_initial', val=0.0, units='s') ivc.add_output('t_duration', val=100.0, units='s') p.model.add_subsystem('time', TimeComp(grid_data=gd, units='s')) p.model.connect('t_initial', 'time.t_initial') p.model.connect('t_duration', 'time.t_duration') p.setup(check=True, force_alloc_complex=True) p.run_model() # Affine transform the nodes [0, 100] dt_dptau = (p['t_duration'] - p['t_initial']) / 2.0 nodes = [] dt_dstau_per_node = [] for i in range(gd.num_segments): a, b = gd.segment_ends[i], gd.segment_ends[ i + 1] # segment ends in phase tau space # ratio of phase tau to segment tau within the segment dptau_dstau = (b - a) / 2.0 dt_dstau = dt_dptau * dptau_dstau * np.ones( gd.subset_num_nodes_per_segment['all'][i]) dt_dstau_per_node.extend(dt_dstau.tolist()) # nodes of current segment in segment tau space nodes_segi_stau = _lgr_nodes[gd.transcription_order[i]] # nodes of current segment in phase tau space nodes_segi_ptau = a + (nodes_segi_stau + 1) * dptau_dstau # nodes in time nodes_time = (nodes_segi_ptau + 1) * dt_dptau nodes.extend(nodes_time.tolist()) assert_almost_equal(p['time.time'], nodes, decimal=4) assert_almost_equal(p['time.dt_dstau'], dt_dstau_per_node)
def setUp(self): gd = GridData(num_segments=2, segment_ends=np.array([0., 2., 4.]), transcription='radau-ps', transcription_order=3) self.gd = gd self.p = Problem(model=Group()) control_opts = { 'u': { 'units': 'm', 'shape': (1, ), 'dynamic': True, 'opt': True }, 'v': { 'units': 'm', 'shape': (3, 2), 'dynamic': True, 'opt': True } } indep_comp = IndepVarComp() self.p.model.add_subsystem('indep', indep_comp, promotes=['*']) indep_comp.add_output('controls:u', val=np.zeros((gd.subset_num_nodes['all'], 1)), units='m') indep_comp.add_output('controls:v', val=np.zeros((gd.subset_num_nodes['all'], 3, 2)), units='m') self.p.model.add_subsystem('endpoint_defect_comp', subsys=ControlEndpointDefectComp( grid_data=gd, control_options=control_opts)) self.p.model.connect('controls:u', 'endpoint_defect_comp.controls:u') self.p.model.connect('controls:v', 'endpoint_defect_comp.controls:v') self.p.setup(force_alloc_complex=True) self.p['controls:u'] = np.random.random( (gd.subset_num_nodes['all'], 1)) self.p['controls:v'] = np.random.random( (gd.subset_num_nodes['all'], 3, 2)) self.p.run_model()
def test_control_interp_scalar(self, transcription='gauss-lobatto', compressed=True): segends = np.array([0.0, 3.0, 10.0]) gd = GridData(num_segments=2, transcription_order=5, segment_ends=segends, transcription=transcription, compressed=compressed) p = Problem(model=Group()) controls = { 'a': { 'units': 'm', 'shape': (1, ), 'dynamic': True }, 'b': { 'units': 'm', 'shape': (1, ), 'dynamic': True } } ivc = IndepVarComp() p.model.add_subsystem('ivc', ivc, promotes_outputs=['*']) ivc.add_output('controls:a', val=np.zeros((gd.subset_num_nodes['control_input'], 1)), units='m') ivc.add_output('controls:b', val=np.zeros((gd.subset_num_nodes['control_input'], 1)), units='m') ivc.add_output('t_initial', val=0.0, units='s') ivc.add_output('t_duration', val=10.0, units='s') p.model.add_subsystem('time_comp', subsys=TimeComp(grid_data=gd, units='s'), promotes_inputs=['t_initial', 't_duration'], promotes_outputs=['time', 'dt_dstau']) p.model.add_subsystem('control_interp_comp', subsys=ControlInterpComp( grid_data=gd, control_options=controls, time_units='s'), promotes_inputs=['controls:*']) p.model.connect('dt_dstau', 'control_interp_comp.dt_dstau') p.setup(force_alloc_complex=True) p['t_initial'] = 0.0 p['t_duration'] = 3.0 p.run_model() t = p['time'] p['controls:a'][:, 0] = f_a(t[gd.subset_node_indices['control_input']]) p['controls:b'][:, 0] = f_b(t[gd.subset_node_indices['control_input']]) p.run_model() a_value_expected = f_a(t) b_value_expected = f_b(t) a_rate_expected = f1_a(t) b_rate_expected = f1_b(t) a_rate2_expected = f2_a(t) b_rate2_expected = f2_b(t) assert_almost_equal(p['control_interp_comp.control_values:a'], np.atleast_2d(a_value_expected).T) assert_almost_equal(p['control_interp_comp.control_values:b'], np.atleast_2d(b_value_expected).T) assert_almost_equal(p['control_interp_comp.control_rates:a_rate'], np.atleast_2d(a_rate_expected).T) assert_almost_equal(p['control_interp_comp.control_rates:b_rate'], np.atleast_2d(b_rate_expected).T) assert_almost_equal(p['control_interp_comp.control_rates:a_rate2'], np.atleast_2d(a_rate2_expected).T) assert_almost_equal(p['control_interp_comp.control_rates:b_rate2'], np.atleast_2d(b_rate2_expected).T) np.set_printoptions(linewidth=1024) cpd = p.check_partials(compact_print=False, out_stream=None, method='cs') assert_check_partials(cpd)
def test_state_interp_comp_radau(self): gd = GridData(num_segments=1, transcription_order=3, segment_ends=np.array([0, 10]), transcription='radau-ps') p = Problem(model=Group()) states = { 'x': { 'units': 'm', 'shape': (1, ) }, 'v': { 'units': 'm/s', 'shape': (1, ) } } X_ivc = IndepVarComp() p.model.add_subsystem('X_ivc', X_ivc, promotes=['state_disc:x', 'state_disc:v']) X_ivc.add_output('state_disc:x', val=np.zeros(gd.subset_num_nodes['state_disc']), units='m') X_ivc.add_output('state_disc:v', val=np.zeros(gd.subset_num_nodes['state_disc']), units='m/s') dt_dtau_ivc = IndepVarComp() dt_dtau_ivc.add_output('dt_dstau', val=0.0 * np.zeros(gd.subset_num_nodes['col']), units='s') p.model.add_subsystem('dt_dstau_ivc', dt_dtau_ivc, promotes=['dt_dstau']) p.model.add_subsystem('state_interp_comp', subsys=StateInterpComp(transcription='radau-ps', grid_data=gd, state_options=states, time_units='s')) p.model.connect('state_disc:x', 'state_interp_comp.state_disc:x') p.model.connect('state_disc:v', 'state_interp_comp.state_disc:v') p.model.connect('dt_dstau', 'state_interp_comp.dt_dstau') p.setup(force_alloc_complex=True) lgr_nodes, lgr_weights = lgr(3, include_endpoint=True) t_disc = (lgr_nodes + 1.0) * 5.0 t_col = t_disc[:-1] # Test 1: Let x = t**2, f = 2*t p['state_disc:x'] = t_disc**2 # Test 1: Let v = t**3-10*t**2, f = 3*t**2 - 20*t p['state_disc:v'] = t_disc**3 - 10 * t_disc**2 p['dt_dstau'] = 10 / 2.0 p.run_model() if SHOW_PLOTS: # pragma: no cover f, ax = plt.subplots(2, 1) t_disc = np.array([0, 5, 10]) t_col = np.array([2.5, 7.5]) t = np.linspace(0, 10, 100) x1 = t**2 xdot1 = 2 * t x2 = t**3 - 10 * t**2 xdot2 = 3 * t**2 - 20 * t ax[0].plot(t, x1, 'b-', label='$x$') ax[0].plot(t, xdot1, 'b--', label='$\dot{x}$') ax[0].plot(t_disc, p['state_disc:x'], 'bo', label='$X_d:x$') ax[0].plot(t_col, p['state_interp_comp.state_col:x'], 'bv', label='$X_c:x$') ax[0].plot(t_col, p['state_interp_comp.staterate_col:x'], marker='v', color='None', mec='b', label='$Xdot_c:x$') ax[1].plot(t, x2, 'r-', label='$v$') ax[1].plot(t, xdot2, 'r--', label='$\dot{v}$') ax[1].plot(t_disc, p['state_disc:v'], 'ro', label='$X_d:v$') ax[1].plot(t_col, p['state_interp_comp.state_col:v'], 'rv', label='$X_c:v$') ax[1].plot(t_col, p['state_interp_comp.staterate_col:v'], marker='v', color='None', mec='r', label='$Xdot_c:v$') ax[0].legend(loc='upper left', ncol=3) ax[1].legend(loc='upper left', ncol=3) plt.show() # Test 1 assert_almost_equal(p['state_interp_comp.staterate_col:x'][:, 0], 2 * t_col) # Test 2 assert_almost_equal(p['state_interp_comp.staterate_col:v'][:, 0], 3 * t_col**2 - 20 * t_col) cpd = p.check_partials(compact_print=True, method='cs') assert_check_partials(cpd, atol=1.0E-5)
def test_state_interp_comp_lobatto(self): segends = np.array([0.0, 3.0, 10.0]) gd = GridData(num_segments=2, transcription_order=3, segment_ends=segends, transcription='gauss-lobatto') p = Problem(model=Group()) states = { 'x': { 'units': 'm', 'shape': (1, ) }, 'v': { 'units': 'm/s', 'shape': (1, ) } } X_ivc = IndepVarComp() p.model.add_subsystem('X_ivc', X_ivc, promotes=['state_disc:x', 'state_disc:v']) X_ivc.add_output('state_disc:x', val=np.zeros(gd.subset_num_nodes['state_disc']), units='m') X_ivc.add_output('state_disc:v', val=np.zeros(gd.subset_num_nodes['state_disc']), units='m/s') F_ivc = IndepVarComp() p.model.add_subsystem( 'F_ivc', F_ivc, promotes=['staterate_disc:x', 'staterate_disc:v']) F_ivc.add_output('staterate_disc:x', val=np.zeros(gd.subset_num_nodes['state_disc']), units='m/s') F_ivc.add_output('staterate_disc:v', val=np.zeros(gd.subset_num_nodes['state_disc']), units='m/s**2') dt_dtau_ivc = IndepVarComp() p.model.add_subsystem('dt_dstau_ivc', dt_dtau_ivc, promotes=['dt_dstau']) dt_dtau_ivc.add_output('dt_dstau', val=0.0 * np.zeros(gd.subset_num_nodes['col']), units='s') p.model.add_subsystem('state_interp_comp', subsys=StateInterpComp( transcription='gauss-lobatto', grid_data=gd, state_options=states, time_units='s')) p.model.connect('state_disc:x', 'state_interp_comp.state_disc:x') p.model.connect('state_disc:v', 'state_interp_comp.state_disc:v') p.model.connect('staterate_disc:x', 'state_interp_comp.staterate_disc:x') p.model.connect('staterate_disc:v', 'state_interp_comp.staterate_disc:v') p.model.connect('dt_dstau', 'state_interp_comp.dt_dstau') p.setup(force_alloc_complex=True) segends_disc = segends[np.array((0, 1, 1, 2), dtype=int)] p['state_disc:x'] = [x(t) for t in segends_disc] p['staterate_disc:x'] = [f_x(t) for t in segends_disc] p['state_disc:v'] = [v(t) for t in segends_disc] p['staterate_disc:v'] = [f_v(t) for t in segends_disc] p['dt_dstau'] = (segends[1:] - segends[:-1]) / 2.0 p.run_model() t_disc = segends_disc t_col = (segends[1:] + segends[:-1]) / 2.0 if SHOW_PLOTS: # pragma: no cover f, ax = plt.subplots(2, 1) t = np.linspace(0, 10, 100) x1 = x(t) xdot1 = f_x(t) x2 = v(t) xdot2 = f_v(t) ax[0].plot(t, x1, 'b-', label='$x$') ax[0].plot(t, xdot1, 'b--', label='$\dot{x}$') ax[0].plot(t_disc, p['state_disc:x'], 'bo', label='$X_d:x$') ax[0].plot(t_col, p['state_interp_comp.state_col:x'], 'bv', label='$X_c:x$') ax[0].plot(t_col, p['state_interp_comp.staterate_col:x'], marker='v', color='None', mec='b', label='$Xdot_c:x$') ax[1].plot(t, x2, 'r-', label='$v$') ax[1].plot(t, xdot2, 'r--', label='$\dot{v}$') ax[1].plot(t_disc, p['state_disc:v'], 'ro', label='$X_d:v$') ax[1].plot(t_col, p['state_interp_comp.state_col:v'], 'rv', label='$X_c:v$') ax[1].plot(t_col, p['state_interp_comp.staterate_col:v'], marker='v', color='None', mec='r', label='$Xdot_c:v$') ax[0].legend(loc='upper left', ncol=3) ax[1].legend(loc='upper left', ncol=3) plt.show() # Test 1 assert_almost_equal(p['state_interp_comp.state_col:x'][:, 0], x(t_col)) assert_almost_equal(p['state_interp_comp.staterate_col:x'][:, 0], f_x(t_col)) # Test 2 assert_almost_equal(p['state_interp_comp.state_col:v'][:, 0], v(t_col)) assert_almost_equal(p['state_interp_comp.staterate_col:v'][:, 0], f_v(t_col)) cpd = p.check_partials(compact_print=True, method='cs') assert_check_partials(cpd, atol=5.0E-5)
def test_state_interp_comp_lobatto_vectorized_different_orders(self): segends = np.array([0.0, 3.0, 10.0]) gd = GridData(num_segments=2, transcription_order=[3, 5], segment_ends=segends, transcription='gauss-lobatto') p = Problem(model=Group()) states = {'pos': {'units': 'm', 'shape': (2, )}} X_ivc = IndepVarComp() p.model.add_subsystem('X_ivc', X_ivc, promotes=['state_disc:pos']) X_ivc.add_output('state_disc:pos', val=np.zeros((gd.subset_num_nodes['state_disc'], 2)), units='m') F_ivc = IndepVarComp() p.model.add_subsystem('F_ivc', F_ivc, promotes=['staterate_disc:pos']) F_ivc.add_output('staterate_disc:pos', val=np.zeros((gd.subset_num_nodes['state_disc'], 2)), units='m/s') dt_dtau_ivc = IndepVarComp() p.model.add_subsystem('dt_dstau_ivc', dt_dtau_ivc, promotes=['dt_dstau']) dt_dtau_ivc.add_output('dt_dstau', val=0.0 * np.zeros(gd.subset_num_nodes['col']), units='s') p.model.add_subsystem('state_interp_comp', subsys=StateInterpComp( transcription='gauss-lobatto', grid_data=gd, state_options=states, time_units='s')) p.model.connect('state_disc:pos', 'state_interp_comp.state_disc:pos') p.model.connect('staterate_disc:pos', 'state_interp_comp.staterate_disc:pos') p.model.connect('dt_dstau', 'state_interp_comp.dt_dstau') p.setup(force_alloc_complex=True) segends_disc = np.array((0, 3, 3, 6.5, 10)) p['state_disc:pos'][:, 0] = [x(t) for t in segends_disc ] # [0.0, 25.0, 25.0, 100.0] p['staterate_disc:pos'][:, 0] = [f_x(t) for t in segends_disc] p['state_disc:pos'][:, 1] = [v(t) for t in segends_disc] p['staterate_disc:pos'][:, 1] = [f_v(t) for t in segends_disc] p['dt_dstau'] = [3.0 / 2., 7.0 / 2, 7.0 / 2] p.run_model() cpd = p.check_partials(compact_print=True, method='cs') assert_check_partials(cpd, atol=5.0E-5)
def setUp(self): transcription = 'gauss-lobatto' gd = GridData(num_segments=4, segment_ends=np.array([0., 2., 4., 5., 12.]), transcription=transcription, transcription_order=3) self.p = Problem(model=Group()) state_options = { 'x': { 'units': 'm', 'shape': (1, ) }, 'v': { 'units': 'm/s', 'shape': (3, 2) } } indep_comp = IndepVarComp() self.p.model.add_subsystem('indep', indep_comp, promotes_outputs=['*']) indep_comp.add_output('dt_dstau', val=np.zeros((gd.subset_num_nodes['col']))) indep_comp.add_output('f_approx:x', val=np.zeros((gd.subset_num_nodes['col'], 1)), units='m') indep_comp.add_output('f_computed:x', val=np.zeros((gd.subset_num_nodes['col'], 1)), units='m') indep_comp.add_output('f_approx:v', val=np.zeros((gd.subset_num_nodes['col'], 3, 2)), units='m/s') indep_comp.add_output('f_computed:v', val=np.zeros((gd.subset_num_nodes['col'], 3, 2)), units='m/s') self.p.model.add_subsystem('defect_comp', subsys=CollocationComp( grid_data=gd, state_options=state_options)) self.p.model.connect('f_approx:x', 'defect_comp.f_approx:x') self.p.model.connect('f_approx:v', 'defect_comp.f_approx:v') self.p.model.connect('f_computed:x', 'defect_comp.f_computed:x') self.p.model.connect('f_computed:v', 'defect_comp.f_computed:v') self.p.model.connect('dt_dstau', 'defect_comp.dt_dstau') self.p.setup(force_alloc_complex=True) self.p['dt_dstau'] = np.random.random(gd.subset_num_nodes['col']) self.p['f_approx:x'] = np.random.random( (gd.subset_num_nodes['col'], 1)) self.p['f_approx:v'] = np.random.random( (gd.subset_num_nodes['col'], 3, 2)) self.p['f_computed:x'] = np.random.random( (gd.subset_num_nodes['col'], 1)) self.p['f_computed:v'] = np.random.random( (gd.subset_num_nodes['col'], 3, 2)) self.p.run_model()
def test_continuity_comp(self, transcription='gauss-lobatto', compressed='compressed'): num_seg = 3 gd = GridData(num_segments=num_seg, transcription_order=[5, 3, 3], segment_ends=[0.0, 3.0, 10.0, 20], transcription=transcription, compressed=compressed == 'compressed') self.p = Problem(model=Group()) ivp = self.p.model.add_subsystem('ivc', subsys=IndepVarComp(), promotes_outputs=['*']) ndn = gd.subset_num_nodes['state_disc'] nn = gd.subset_num_nodes['all'] ivp.add_output('x', val=np.arange(nn), units='m') ivp.add_output('y', val=np.arange(nn), units='m/s') ivp.add_output('u', val=np.zeros((nn, 3)), units='deg') ivp.add_output('v', val=np.arange(nn), units='N') ivp.add_output('u_rate', val=np.zeros((nn, 3)), units='deg/s') ivp.add_output('v_rate', val=np.arange(nn), units='N/s') ivp.add_output('u_rate2', val=np.zeros((nn, 3)), units='deg/s**2') ivp.add_output('v_rate2', val=np.arange(nn), units='N/s**2') ivp.add_output('t_duration', val=121.0, units='s') self.p.model.add_design_var('x', lower=0, upper=100) state_options = { 'x': StateOptionsDictionary(), 'y': StateOptionsDictionary() } control_options = { 'u': ControlOptionsDictionary(), 'v': ControlOptionsDictionary() } state_options['x']['units'] = 'm' state_options['y']['units'] = 'm/s' control_options['u']['units'] = 'deg' control_options['u']['shape'] = (3, ) control_options['u']['continuity'] = True control_options['v']['units'] = 'N' if transcription == 'gauss-lobatto': cnty_comp = GaussLobattoContinuityComp( grid_data=gd, time_units='s', state_options=state_options, control_options=control_options) elif transcription == 'radau-ps': cnty_comp = RadauPSContinuityComp(grid_data=gd, time_units='s', state_options=state_options, control_options=control_options) else: raise ValueError('unrecognized transcription') self.p.model.add_subsystem('cnty_comp', subsys=cnty_comp) # The sub-indices of state_disc indices that are segment ends segment_end_idxs = gd.subset_node_indices['segment_ends'] self.p.model.connect('x', 'cnty_comp.states:x', src_indices=segment_end_idxs) self.p.model.connect('y', 'cnty_comp.states:y', src_indices=segment_end_idxs) self.p.model.connect('t_duration', 'cnty_comp.t_duration') size_u = nn * np.prod(control_options['u']['shape']) src_idxs_u = np.arange(size_u).reshape((nn, ) + control_options['u']['shape']) src_idxs_u = src_idxs_u[gd.subset_node_indices['segment_ends'], ...] size_v = nn * np.prod(control_options['v']['shape']) src_idxs_v = np.arange(size_v).reshape((nn, ) + control_options['v']['shape']) src_idxs_v = src_idxs_v[gd.subset_node_indices['segment_ends'], ...] self.p.model.connect('u', 'cnty_comp.controls:u', src_indices=src_idxs_u, flat_src_indices=True) self.p.model.connect('u_rate', 'cnty_comp.control_rates:u_rate', src_indices=src_idxs_u, flat_src_indices=True) self.p.model.connect('u_rate2', 'cnty_comp.control_rates:u_rate2', src_indices=src_idxs_u, flat_src_indices=True) self.p.model.connect('v', 'cnty_comp.controls:v', src_indices=src_idxs_v, flat_src_indices=True) self.p.model.connect('v_rate', 'cnty_comp.control_rates:v_rate', src_indices=src_idxs_v, flat_src_indices=True) self.p.model.connect('v_rate2', 'cnty_comp.control_rates:v_rate2', src_indices=src_idxs_v, flat_src_indices=True) self.p.setup(check=True, force_alloc_complex=True) self.p['x'] = np.random.rand(*self.p['x'].shape) self.p['y'] = np.random.rand(*self.p['y'].shape) self.p['u'] = np.random.rand(*self.p['u'].shape) self.p['v'] = np.random.rand(*self.p['v'].shape) self.p['u_rate'] = np.random.rand(*self.p['u'].shape) self.p['v_rate'] = np.random.rand(*self.p['v'].shape) self.p['u_rate2'] = np.random.rand(*self.p['u'].shape) self.p['v_rate2'] = np.random.rand(*self.p['v'].shape) self.p.run_model() for state in ('x', 'y'): expected_val = self.p[state][segment_end_idxs, ...][2::2, ...] - \ self.p[state][segment_end_idxs, ...][1:-1:2, ...] assert_rel_error( self, self.p['cnty_comp.defect_states:{0}'.format(state)], expected_val.reshape((num_seg - 1, ) + state_options[state]['shape'])) for ctrl in ('u', 'v'): expected_val = self.p[ctrl][segment_end_idxs, ...][2::2, ...] - \ self.p[ctrl][segment_end_idxs, ...][1:-1:2, ...] assert_rel_error( self, self.p['cnty_comp.defect_controls:{0}'.format(ctrl)], expected_val.reshape((num_seg - 1, ) + control_options[ctrl]['shape'])) np.set_printoptions(linewidth=1024) cpd = self.p.check_partials(method='cs', out_stream=None) assert_check_partials(cpd)
def setUp(self): transcription = 'radau-ps' self.gd = gd = GridData(num_segments=2, transcription_order=3, segment_ends=[0.0, 3.0, 10.0], transcription=transcription) ndn = gd.subset_num_nodes['disc'] self.p = Problem(model=Group()) controls = { 'a': ControlOptionsDictionary(), 'b': ControlOptionsDictionary(), 'c': ControlOptionsDictionary(), 'd': ControlOptionsDictionary() } controls['a'].update({'units': 'm', 'shape': (1, ), 'opt': False}) controls['b'].update({'units': 's', 'shape': (3, ), 'opt': False}) controls['c'].update({'units': 'kg', 'shape': (3, 3), 'opt': False}) ivc = IndepVarComp() self.p.model.add_subsystem('ivc', ivc, promotes_outputs=['*']) ivc.add_output('a_disc', val=np.zeros((ndn, 1)), units='m') ivc.add_output('b_disc', val=np.zeros((ndn, 3)), units='s') ivc.add_output('c_disc', val=np.zeros((ndn, 3, 3)), units='kg') path_comp = RadauPathConstraintComp(grid_data=gd) self.p.model.add_subsystem('path_constraints', subsys=path_comp) path_comp._add_path_constraint('a', var_class='ode', shape=(1, ), lower=0, upper=10, units='m') path_comp._add_path_constraint('b', var_class='input_control', shape=(3, ), lower=0, upper=10, units='s') path_comp._add_path_constraint('c', var_class='control_rate2', shape=(3, 3), lower=0, upper=10, units='kg') self.p.model.connect('a_disc', 'path_constraints.all_values:a') self.p.model.connect('b_disc', 'path_constraints.all_values:b') self.p.model.connect('c_disc', 'path_constraints.all_values:c') self.p.setup() self.p.run_model()