def test_simple_integration(self): p = om.Problem(model=om.Group()) time_options = TimeOptionsDictionary() time_options['units'] = 's' time_options['targets'] = 't' state_options = {} state_options['y'] = StateOptionsDictionary() state_options['y']['units'] = 'm' state_options['y']['targets'] = 'y' state_options['y']['rate_source'] = 'ydot' gd = GridData(num_segments=4, transcription='gauss-lobatto', transcription_order=3) seg0_comp = SegmentSimulationComp(index=0, grid_data=gd, method='RK45', atol=1.0E-9, rtol=1.0E-9, ode_class=TestODE, time_options=time_options, state_options=state_options) p.model.add_subsystem('segment_0', subsys=seg0_comp) p.setup(check=True) p.set_val('segment_0.time', [0, 0.25, 0.5]) p.set_val('segment_0.initial_states:y', 0.5) p.run_model() assert_rel_error(self, p.get_val('segment_0.states:y', units='m')[-1, ...], 1.425639364649936, tolerance=1.0E-6)
def test_simple_integration(self): p = om.Problem(model=om.Group()) time_options = TimeOptionsDictionary() time_options['units'] = 's' time_options['targets'] = 't' state_options = {} state_options['y'] = StateOptionsDictionary() state_options['y']['units'] = 'm' state_options['y']['targets'] = 'y' state_options['y']['rate_source'] = 'ydot' # Non-standard way to assign state options, so we need this state_options['y']['shape'] = (1, ) gd = GridData(num_segments=4, transcription='gauss-lobatto', transcription_order=3) sim_options = SimulateOptionsDictionary() sim_options['rtol'] = 1.0E-9 sim_options['atol'] = 1.0E-9 seg0_comp = SegmentSimulationComp(index=0, grid_data=gd, simulate_options=sim_options, ode_class=TestODE, time_options=time_options, state_options=state_options) p.model.add_subsystem('segment_0', subsys=seg0_comp) p.setup(check=True) p.set_val('segment_0.time', [0, 0.25, 0.5]) p.set_val('segment_0.initial_states:y', 0.5) p.run_model() assert_near_equal(p.get_val('segment_0.states:y', units='m')[-1, ...], 1.425639364649936, tolerance=1.0E-6)
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 = om.Problem(model=om.Group()) ivp = self.p.model.add_subsystem('ivc', subsys=om.IndepVarComp(), promotes_outputs=['*']) 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 num_seg_ends = gd.subset_num_nodes['segment_ends'] segment_end_idxs = np.reshape(gd.subset_node_indices['segment_ends'], newshape=(num_seg_ends, 1)) if compressed != 'compressed': 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'], ...] # if transcription =='radau-ps' or compressed != 'compressed': 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) # if transcription =='radau-ps' or compressed != 'compressed': 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() if compressed != 'compressed': for state in ('x', 'y'): xpectd = self.p[state][segment_end_idxs, ...][2::2, ...] - \ self.p[state][segment_end_idxs, ...][1:-1:2, ...] assert_near_equal(self.p['cnty_comp.defect_states:{0}'.format(state)], xpectd.reshape((num_seg - 1,) + state_options[state]['shape'])) for ctrl in ('u', 'v'): xpectd = self.p[ctrl][segment_end_idxs, ...][2::2, ...] - \ self.p[ctrl][segment_end_idxs, ...][1:-1:2, ...] if compressed != 'compressed': assert_near_equal(self.p['cnty_comp.defect_controls:{0}'.format(ctrl)], xpectd.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 test_scalar_state_and_control(self): n = 101 p = om.Problem(model=om.Group()) time_options = TimeOptionsDictionary() time_options['units'] = 's' state_options = {} state_options['x'] = StateOptionsDictionary() state_options['x']['units'] = 'm' state_options['x']['shape'] = (1, ) control_options = {} control_options['theta'] = ControlOptionsDictionary() control_options['theta']['units'] = 'rad' control_options['theta']['shape'] = (1, ) ivc = om.IndepVarComp() ivc.add_output(name='phase:time', val=np.zeros(n), units='s') ivc.add_output(name='phase:initial_jump:time', val=100.0 * np.ones(1), units='s') ivc.add_output(name='phase:final_jump:time', val=1.0 * np.ones(1), units='s') ivc.add_output(name='phase:x', val=np.zeros(n), units='m') ivc.add_output(name='phase:initial_jump:x', val=np.zeros(state_options['x']['shape']), units='m') ivc.add_output(name='phase:final_jump:x', val=np.zeros(state_options['x']['shape']), units='m') ivc.add_output(name='phase:theta', val=np.zeros(n), units='rad') ivc.add_output(name='phase:initial_jump:theta', val=np.zeros(control_options['theta']['shape']), units='rad') ivc.add_output(name='phase:final_jump:theta', val=np.zeros(control_options['theta']['shape']), units='rad') p.model.add_subsystem('ivc', subsys=ivc, promotes_outputs=['*']) p.model.add_subsystem('initial_conditions', subsys=EndpointConditionsComp( loc='initial', time_options=time_options, state_options=state_options, control_options=control_options), promotes_outputs=['*']) p.model.add_subsystem('final_conditions', subsys=EndpointConditionsComp( loc='final', time_options=time_options, state_options=state_options, control_options=control_options), promotes_outputs=['*']) p.model.connect('phase:time', 'initial_conditions.initial_value:time') p.model.connect('phase:time', 'final_conditions.final_value:time') p.model.connect('phase:x', 'initial_conditions.initial_value:x') p.model.connect('phase:x', 'final_conditions.final_value:x') p.model.connect('phase:theta', 'initial_conditions.initial_value:theta') p.model.connect('phase:theta', 'final_conditions.final_value:theta') p.model.connect('phase:initial_jump:time', 'initial_conditions.initial_jump:time') p.model.connect('phase:final_jump:time', 'final_conditions.final_jump:time') p.model.connect('phase:initial_jump:x', 'initial_conditions.initial_jump:x') p.model.connect('phase:final_jump:x', 'final_conditions.final_jump:x') p.model.connect('phase:initial_jump:theta', 'initial_conditions.initial_jump:theta') p.model.connect('phase:final_jump:theta', 'final_conditions.final_jump:theta') p.model.linear_solver = om.DirectSolver() p.setup(force_alloc_complex=True) p['phase:time'] = np.linspace(0, 500, n) p['phase:time'] = np.linspace(0, 500, n) p['phase:x'] = np.linspace(0, 10, n) p['phase:theta'] = np.linspace(-1, 1, n) p['phase:initial_jump:time'] = 50.0 p['phase:final_jump:time'] = 75.0 p['phase:initial_jump:x'] = 100.0 p['phase:final_jump:x'] = 200.0 p['phase:initial_jump:theta'] = -1.0 p['phase:final_jump:theta'] = -1.0 p.run_model() assert_almost_equal(p['time--'], p['phase:time'][0] - p['phase:initial_jump:time']) assert_almost_equal(p['time-+'], p['phase:time'][0]) assert_almost_equal(p['time++'], p['phase:time'][-1] + p['phase:final_jump:time']) assert_almost_equal(p['time+-'], p['phase:time'][-1]) assert_almost_equal(p['states:x--'], p['phase:x'][0] - p['phase:initial_jump:x']) assert_almost_equal(p['states:x++'], p['phase:x'][-1] + p['phase:final_jump:x']) assert_almost_equal( p['controls:theta--'], p['phase:theta'][0] - p['phase:initial_jump:theta']) assert_almost_equal(p['controls:theta++'], p['phase:theta'][-1] + p['phase:final_jump:theta']) cpd = p.check_partials(compact_print=True, method='cs') assert_check_partials(cpd)
def test_vector_state_and_control(self): n = 101 p = om.Problem(model=om.Group()) time_options = TimeOptionsDictionary() time_options['units'] = 's' state_options = {} state_options['pos'] = StateOptionsDictionary() state_options['pos']['units'] = 'm' state_options['pos']['shape'] = (3, ) control_options = {} control_options['cmd'] = ControlOptionsDictionary() control_options['cmd']['units'] = 'rad' control_options['cmd']['shape'] = (3, ) ivc = om.IndepVarComp() ivc.add_output(name='phase:time', val=np.zeros(n), units='s') ivc.add_output(name='phase:initial_jump:time', val=100.0 * np.ones(1), units='s') ivc.add_output(name='phase:pos', val=np.zeros((n, 3)), units='m') ivc.add_output(name='phase:initial_jump:pos', val=np.zeros(state_options['pos']['shape']), units='m') ivc.add_output(name='phase:final_jump:pos', val=np.zeros(state_options['pos']['shape']), units='m') ivc.add_output(name='phase:cmd', val=np.zeros((n, 3)), units='rad') ivc.add_output(name='phase:initial_jump:cmd', val=np.zeros(control_options['cmd']['shape']), units='rad') ivc.add_output(name='phase:final_jump:cmd', val=np.zeros(control_options['cmd']['shape']), units='rad') p.model.add_subsystem('ivc', subsys=ivc, promotes_outputs=['*']) p.model.add_subsystem('initial_conditions', subsys=EndpointConditionsComp( loc='initial', time_options=time_options, state_options=state_options, control_options=control_options), promotes_outputs=['*']) p.model.add_subsystem('final_conditions', subsys=EndpointConditionsComp( loc='final', time_options=time_options, state_options=state_options, control_options=control_options), promotes_outputs=['*']) p.model.connect('phase:time', 'initial_conditions.initial_value:time') p.model.connect('phase:time', 'final_conditions.final_value:time') p.model.connect('phase:pos', 'initial_conditions.initial_value:pos') p.model.connect('phase:pos', 'final_conditions.final_value:pos') p.model.connect('phase:initial_jump:pos', 'initial_conditions.initial_jump:pos') p.model.connect('phase:final_jump:pos', 'final_conditions.final_jump:pos') p.model.connect('phase:cmd', 'initial_conditions.initial_value:cmd') p.model.connect('phase:cmd', 'final_conditions.final_value:cmd') p.model.connect('phase:initial_jump:cmd', 'initial_conditions.initial_jump:cmd') p.model.connect('phase:final_jump:cmd', 'final_conditions.final_jump:cmd') p.model.linear_solver = om.DirectSolver() p.model.options['assembled_jac_type'] = 'csc' p.setup(force_alloc_complex=True) p['phase:time'] = np.linspace(0, 500, n) p['phase:pos'][:, 0] = np.linspace(0, 10, n) p['phase:pos'][:, 1] = np.linspace(0, 20, n) p['phase:pos'][:, 2] = np.linspace(0, 30, n) p['phase:initial_jump:pos'] = np.array([7, 8, 9]) p['phase:final_jump:pos'] = np.array([4, 5, 6]) p['phase:cmd'][:, 0] = np.linspace(0, 5, n) p['phase:cmd'][:, 1] = np.linspace(0, 6, n) p['phase:cmd'][:, 2] = np.linspace(0, 7, n) p['phase:initial_jump:cmd'] = np.array([1, 2, 3]) p['phase:final_jump:cmd'] = np.array([10, 11, 12]) p.run_model() assert_almost_equal(p['states:pos--'], p['phase:pos'][0, :] - p['phase:initial_jump:pos']) assert_almost_equal(p['states:pos++'], p['phase:pos'][-1, :] + p['phase:final_jump:pos']) assert_almost_equal(p['controls:cmd--'], p['phase:cmd'][0, :] - p['phase:initial_jump:cmd']) assert_almost_equal(p['controls:cmd++'], p['phase:cmd'][-1, :] + p['phase:final_jump:cmd']) cpd = p.check_partials(compact_print=True, method='cs') assert_check_partials(cpd)