def test(self):
        """
        A simple example to compute power as the dot-product of force and velocity vectors
        at 100 points simultaneously.
        """
        import numpy as np
        from openmdao.api import Problem, Group, IndepVarComp, DotProductComp
        from openmdao.utils.assert_utils import assert_rel_error

        n = 100

        p = Problem(model=Group())

        ivc = IndepVarComp()
        ivc.add_output(name='force', shape=(n, 3))
        ivc.add_output(name='vel', shape=(n, 3))

        p.model.add_subsystem(name='ivc',
                              subsys=ivc,
                              promotes_outputs=['force', 'vel'])

        dp_comp = DotProductComp(vec_size=n, length=3, a_name='F', b_name='v', c_name='P',
                                 a_units='N', b_units='m/s', c_units='W')

        p.model.add_subsystem(name='dot_prod_comp', subsys=dp_comp)

        p.model.connect('force', 'dot_prod_comp.F')
        p.model.connect('vel', 'dot_prod_comp.v')

        p.setup()

        p['force'] = np.random.rand(n, 3)
        p['vel'] = np.random.rand(n, 3)

        p.run_model()

        print(p.get_val('dot_prod_comp.P', units='W'))

        # Verify the results against numpy.dot in a for loop.
        for i in range(n):
            a_i = p['force'][i, :]
            b_i = p['vel'][i, :]
            expected_i = np.dot(a_i, b_i) / 1000.0
            assert_rel_error(self, p.get_val('dot_prod_comp.P', units='kW')[i], expected_i)
    def test(self):
        """
        A simple example to compute the resultant force on an aircraft and demonstrate the AddSubtract component
        """
        import numpy as np
        from openmdao.api import Problem, Group, IndepVarComp, AddSubtractComp
        from openmdao.utils.assert_utils import assert_rel_error

        n = 3

        p = Problem(model=Group())

        ivc = IndepVarComp()
        #the vector represents forces at 3 time points (rows) in 2 dimensional plane (cols)
        ivc.add_output(name='thrust', shape=(n,2),units='kN')
        ivc.add_output(name='drag', shape=(n,2),units='kN')
        ivc.add_output(name='lift', shape=(n,2),units='kN')
        ivc.add_output(name='weight', shape=(n,2),units='kN')
        p.model.add_subsystem(name='ivc',
                              subsys=ivc,
                              promotes_outputs=['thrust', 'drag', 'lift', 'weight'])

        #construct an adder/subtracter here. create a relationship through the add_equation method
        adder = AddSubtractComp()
        adder.add_equation('total_force',input_names=['thrust','drag','lift','weight'],vec_size=n,length=2, scaling_factors=[1,-1,1,-1], units='kN')
        #note the scaling factors. we assume all forces are positive sign upstream

        p.model.add_subsystem(name='totalforcecomp', subsys=adder)

        p.model.connect('thrust', 'totalforcecomp.thrust')
        p.model.connect('drag', 'totalforcecomp.drag')
        p.model.connect('lift', 'totalforcecomp.lift')
        p.model.connect('weight', 'totalforcecomp.weight')

        p.setup()

        #set thrust to exceed drag, weight to equal lift for this scenario
        p['thrust'][:,0] = [500, 600, 700]
        p['drag'][:,0] = [400, 400, 400]
        p['weight'][:,1] = [1000, 1001, 1002]
        p['lift'][:,1] = [1000, 1000, 1000]

        p.run_model()

        # print(p.get_val('totalforcecomp.total_force', units='kN'))

        # Verify the results
        expected_i = np.array([[100, 200, 300],[0, -1, -2]]).T
        assert_rel_error(self, p.get_val('totalforcecomp.total_force', units='kN'), expected_i)
class TestUnits(unittest.TestCase):

    def setUp(self):
        self.nn = 5

        self.p = Problem(model=Group())

        ivc = IndepVarComp()
        ivc.add_output(name='a', shape=(self.nn, 3), units='lbf')
        ivc.add_output(name='b', shape=(self.nn, 3), units='ft/s')

        self.p.model.add_subsystem(name='ivc',
                                   subsys=ivc,
                                   promotes_outputs=['a', 'b'])

        self.p.model.add_subsystem(name='dot_prod_comp',
                                   subsys=DotProductComp(vec_size=self.nn,
                                                         a_units='N', b_units='m/s',
                                                         c_units='W'))

        self.p.model.connect('a', 'dot_prod_comp.a')
        self.p.model.connect('b', 'dot_prod_comp.b')

        self.p.setup()

        self.p['a'] = np.random.rand(self.nn, 3)
        self.p['b'] = np.random.rand(self.nn, 3)

        self.p.run_model()

    def test_results(self):

        for i in range(self.nn):
            a_i = self.p['a'][i, :]
            b_i = self.p['b'][i, :]
            c_i = self.p.get_val('dot_prod_comp.c', units='hp')[i]
            expected_i = np.dot(a_i, b_i) / 550.0

            np.testing.assert_almost_equal(c_i, expected_i)

    def test_partials(self):
        np.set_printoptions(linewidth=1024)
        cpd = self.p.check_partials(compact_print=True)

        for comp in cpd:
            for (var, wrt) in cpd[comp]:
                np.testing.assert_almost_equal(actual=cpd[comp][var, wrt]['J_fwd'],
                                               desired=cpd[comp][var, wrt]['J_fd'],
                                               decimal=6)
class TestUnits(unittest.TestCase):

    def setUp(self):
        self.nn = 5

        self.p = Problem(model=Group())

        ivc = IndepVarComp()
        ivc.add_output(name='A', shape=(self.nn, 3, 3), units='ft')
        ivc.add_output(name='x', shape=(self.nn, 3), units='lbf')

        self.p.model.add_subsystem(name='ivc',
                                   subsys=ivc,
                                   promotes_outputs=['A', 'x'])

        self.p.model.add_subsystem(name='mat_vec_product_comp',
                                   subsys=MatrixVectorProductComp(vec_size=self.nn,
                                                                  A_units='m', x_units='N',
                                                                  b_units='N*m'))

        self.p.model.connect('A', 'mat_vec_product_comp.A')
        self.p.model.connect('x', 'mat_vec_product_comp.x')

        self.p.setup(force_alloc_complex=True)

        self.p['A'] = np.random.rand(self.nn, 3, 3)
        self.p['x'] = np.random.rand(self.nn, 3)

        self.p.run_model()

    def test_results(self):

        for i in range(self.nn):
            A_i = self.p['A'][i, :, :]
            x_i = self.p['x'][i, :]
            b_i = self.p.get_val('mat_vec_product_comp.b', units='ft*lbf')[i, :]

            expected_i = np.dot(A_i, x_i)
            np.testing.assert_almost_equal(b_i, expected_i)

    def test_partials(self):
        np.set_printoptions(linewidth=1024)
        cpd = self.p.check_partials(out_stream=None, method='cs')

        for comp in cpd:
            for (var, wrt) in cpd[comp]:
                np.testing.assert_almost_equal(actual=cpd[comp][var, wrt]['J_fwd'],
                                               desired=cpd[comp][var, wrt]['J_fd'],
                                               decimal=6)
Example #5
0
    def test(self):
        """
        An example demonstrating a trivial use case of DemuxComp
        """
        import numpy as np
        from openmdao.api import Problem, Group, IndepVarComp, DemuxComp, ExecComp
        from openmdao.utils.assert_utils import assert_rel_error

        # The number of elements to be demuxed
        n = 3

        # The size of each element to be demuxed
        m = 100

        p = Problem(model=Group())

        ivc = IndepVarComp()
        ivc.add_output(name='pos_ecef', shape=(m, 3), units='km')

        p.model.add_subsystem(name='ivc',
                              subsys=ivc,
                              promotes_outputs=['pos_ecef'])

        mux_comp = p.model.add_subsystem(name='demux',
                                         subsys=DemuxComp(vec_size=n))

        mux_comp.add_var('pos', shape=(m, n), axis=1, units='km')

        p.model.add_subsystem(name='longitude_comp',
                              subsys=ExecComp('long = atan(y/x)',
                                              x={'value': np.ones(m), 'units': 'km'},
                                              y={'value': np.ones(m), 'units': 'km'},
                                              long={'value': np.ones(m), 'units': 'rad'}))

        p.model.connect('demux.pos_0', 'longitude_comp.x')
        p.model.connect('demux.pos_1', 'longitude_comp.y')
        p.model.connect('pos_ecef', 'demux.pos')

        p.setup()

        p['pos_ecef'][:, 0] = 6378 * np.cos(np.linspace(0, 2*np.pi, m))
        p['pos_ecef'][:, 1] = 6378 * np.sin(np.linspace(0, 2*np.pi, m))
        p['pos_ecef'][:, 2] = 0.0

        p.run_model()

        expected = np.arctan(p['pos_ecef'][:, 1] / p['pos_ecef'][:, 0])
        assert_rel_error(self, p.get_val('longitude_comp.long'), expected)
class TestUnits(unittest.TestCase):

    def setUp(self):
        self.nn = 5

        self.p = Problem(model=Group())

        ivc = IndepVarComp()
        ivc.add_output(name='a', shape=(self.nn, 3), units='m')

        self.p.model.add_subsystem(name='ivc',
                                   subsys=ivc,
                                   promotes_outputs=['a'])

        self.p.model.add_subsystem(name='vec_mag_comp',
                                   subsys=VectorMagnitudeComp(vec_size=self.nn, units='m'))

        self.p.model.connect('a', 'vec_mag_comp.a')

        self.p.setup()

        self.p['a'] = 1.0 + np.random.rand(self.nn, 3)

        self.p.run_model()

    def test_results(self):

        for i in range(self.nn):
            a_i = self.p['a'][i, :]
            c_i = self.p.get_val('vec_mag_comp.a_mag', units='ft')[i]
            expected_i = np.sqrt(np.dot(a_i, a_i)) / 0.3048

            np.testing.assert_almost_equal(c_i, expected_i)

    def test_partials(self):
        np.set_printoptions(linewidth=1024)
        cpd = self.p.check_partials(compact_print=True)

        for comp in cpd:
            for (var, wrt) in cpd[comp]:
                np.testing.assert_almost_equal(actual=cpd[comp][var, wrt]['J_fwd'],
                                               desired=cpd[comp][var, wrt]['J_fd'],
                                               decimal=6)
    def test(self):
        import numpy as np
        from openmdao.api import Problem, Group, IndepVarComp, CrossProductComp
        from openmdao.utils.assert_utils import assert_rel_error

        n = 100

        p = Problem(model=Group())

        ivc = IndepVarComp()
        ivc.add_output(name='r', shape=(n, 3))
        ivc.add_output(name='F', shape=(n, 3))

        p.model.add_subsystem(name='ivc',
                              subsys=ivc,
                              promotes_outputs=['r', 'F'])

        p.model.add_subsystem(name='cross_prod_comp',
                              subsys=CrossProductComp(vec_size=n,
                                                      a_name='r', b_name='F', c_name='torque',
                                                      a_units='m', b_units='N', c_units='N*m'))

        p.model.connect('r', 'cross_prod_comp.r')
        p.model.connect('F', 'cross_prod_comp.F')

        p.setup()

        p['r'] = np.random.rand(n, 3)
        p['F'] = np.random.rand(n, 3)

        p.run_model()

        # Check the output in units of ft*lbf to ensure that our units work as expected.
        for i in range(n):
            a_i = p['r'][i, :]
            b_i = p['F'][i, :]
            expected_i = np.cross(a_i, b_i) * 0.73756215
            assert_rel_error(self,
                             p.get_val('cross_prod_comp.torque', units='ft*lbf')[i, :],
                             expected_i, tolerance=1.0E-8)
    def test(self):
        import numpy as np
        from openmdao.api import Problem, Group, IndepVarComp, MatrixVectorProductComp
        from openmdao.utils.assert_utils import assert_rel_error

        nn = 100

        p = Problem(model=Group())

        ivc = IndepVarComp()
        ivc.add_output(name='A', shape=(nn, 3, 3))
        ivc.add_output(name='x', shape=(nn, 3))

        p.model.add_subsystem(name='ivc',
                              subsys=ivc,
                              promotes_outputs=['A', 'x'])

        p.model.add_subsystem(name='mat_vec_product_comp',
                              subsys=MatrixVectorProductComp(A_name='M', vec_size=nn,
                                                             b_name='y', b_units='m'))

        p.model.connect('A', 'mat_vec_product_comp.M')
        p.model.connect('x', 'mat_vec_product_comp.x')

        p.setup()

        p['A'] = np.random.rand(nn, 3, 3)
        p['x'] = np.random.rand(nn, 3)

        p.run_model()

        for i in range(nn):
            A_i = p['A'][i, :, :]
            x_i = p['x'][i, :]

            expected_i = np.dot(A_i, x_i) * 3.2808399
            assert_rel_error(self,
                             p.get_val('mat_vec_product_comp.y', units='ft')[i, :],
                             expected_i,
                             tolerance=1.0E-8)
    def test(self):
        """
        A simple example to compute the magnitude of 3-vectors at at 100 points simultaneously.
        """
        import numpy as np
        from openmdao.api import Problem, Group, IndepVarComp, VectorMagnitudeComp
        from openmdao.utils.assert_utils import assert_rel_error

        n = 100

        p = Problem(model=Group())

        ivc = IndepVarComp()
        ivc.add_output(name='pos', shape=(n, 3), units='m')

        p.model.add_subsystem(name='ivc',
                              subsys=ivc,
                              promotes_outputs=['pos'])

        dp_comp = VectorMagnitudeComp(vec_size=n, length=3, in_name='r', mag_name='r_mag',
                                      units='km')

        p.model.add_subsystem(name='vec_mag_comp', subsys=dp_comp)

        p.model.connect('pos', 'vec_mag_comp.r')

        p.setup()

        p['pos'] = 1.0 + np.random.rand(n, 3)

        p.run_model()

        # Verify the results against numpy.dot in a for loop.
        for i in range(n):
            a_i = p['pos'][i, :]
            expected_i = np.sqrt(np.dot(a_i, a_i)) / 1000.0
            assert_rel_error(self, p.get_val('vec_mag_comp.r_mag')[i], expected_i)
Example #10
0
from dymos import Phase, GaussLobatto
from dymos.examples.brachistochrone.brachistochrone_ode import BrachistochroneODE

p = Problem(model=Group())
phase = Phase(ode_class=BrachistochroneODE,
              transcription=GaussLobatto(num_segments=4, order=[3, 5, 3, 5]))
p.model.add_subsystem('phase0', phase)

p.setup()
p['phase0.t_initial'] = 1.0
p['phase0.t_duration'] = 9.0
p.run_model()

grid_data = phase.options['transcription'].grid_data

t_all = p.get_val('phase0.timeseries.time')
t_disc = t_all[grid_data.subset_node_indices['state_disc'], 0]
t_col = t_all[grid_data.subset_node_indices['col'], 0]


def f(x):  # pragma: no cover
    return np.sin(x) / x + 1


def fu(x):  # pragma: no cover
    return (np.cos(x) * x - np.sin(x)) / x**2


def plot_01():  # pragma: no cover

    fig, axes = plt.subplots(1, 1)
def main():

    num_nodes = 1
    num_blades = 10
    num_radial = 15
    num_cp = 6

    af_filename = 'airfoils/mh117.dat'
    chord = 20.
    theta = 5.0 * np.pi / 180.0
    pitch = 0.

    # Numbers taken from the Aviary group's study of the RVLT tiltwing
    # turboelectric concept vehicle.
    n_props = 4
    hub_diameter = 30.  # cm
    prop_diameter = 15 * 30.48  # 15 ft in cm
    c0 = np.sqrt(1.4 * 287.058 * 300.)  # meters/second
    rho0 = 1.4 * 98600. / (c0 * c0)  # kg/m^3
    omega = 236.  # rad/s

    # Find the thrust per rotor from the vehicle's mass.
    m_full = 6367  # kg
    g = 9.81  # m/s**2
    thrust_vtol = 0.1 * m_full * g / n_props

    prob = Problem()

    comp = IndepVarComp()
    comp.add_discrete_output('B', val=num_blades)
    comp.add_output('rho', val=rho0, shape=num_nodes, units='kg/m**3')
    comp.add_output('mu', val=1., shape=num_nodes, units='N/m**2*s')
    comp.add_output('asound', val=c0, shape=num_nodes, units='m/s')
    comp.add_output('v', val=2., shape=num_nodes, units='m/s')
    comp.add_output('alpha', val=0., shape=num_nodes, units='rad')
    comp.add_output('incidence', val=0., shape=num_nodes, units='rad')
    comp.add_output('precone', val=0., units='deg')
    comp.add_output('hub_diameter',
                    val=hub_diameter,
                    shape=num_nodes,
                    units='cm')
    comp.add_output('prop_diameter',
                    val=prop_diameter,
                    shape=num_nodes,
                    units='cm')
    comp.add_output('pitch', val=pitch, shape=num_nodes, units='rad')
    comp.add_output('chord_dv', val=chord, shape=num_cp, units='cm')
    comp.add_output('theta_dv', val=theta, shape=num_cp, units='rad')
    comp.add_output('thrust_vtol', val=thrust_vtol, shape=num_nodes, units='N')
    prob.model.add_subsystem('indep_var_comp', comp, promotes=['*'])

    comp = GeometryGroup(num_nodes=num_nodes,
                         num_cp=num_cp,
                         num_radial=num_radial)
    prob.model.add_subsystem(
        'geometry_group',
        comp,
        promotes_inputs=[
            'hub_diameter', 'prop_diameter', 'chord_dv', 'theta_dv', 'pitch'
        ],
        promotes_outputs=['radii', 'dradii', 'chord', 'theta'])

    balance_group = Group()

    comp = SimpleInflow(num_nodes=num_nodes, num_radial=num_radial)
    balance_group.add_subsystem(
        'inflow_comp',
        comp,
        promotes_inputs=['v', 'omega', 'radii', 'precone'],
        promotes_outputs=['Vx', 'Vy'])

    comp = CCBladeGroup(num_nodes=num_nodes,
                        num_radial=num_radial,
                        num_blades=num_blades,
                        af_filename=af_filename,
                        turbine=False)
    balance_group.add_subsystem(
        'ccblade_group',
        comp,
        promotes_inputs=[
            'B', 'radii', 'dradii', 'chord', 'theta', 'rho', 'mu', 'asound',
            'v', 'precone', 'omega', 'Vx', 'Vy', 'precone', 'hub_diameter',
            'prop_diameter'
        ],
        promotes_outputs=['thrust', 'torque', 'efficiency'])

    comp = BalanceComp()
    comp.add_balance(
        name='omega',
        eq_units='N',
        lhs_name='thrust',
        rhs_name='thrust_vtol',
        val=omega,
        units='rad/s',
        # lower=0.,
    )
    balance_group.add_subsystem('thrust_balance_comp', comp, promotes=['*'])

    balance_group.linear_solver = DirectSolver(assemble_jac=True)
    balance_group.nonlinear_solver = NewtonSolver(maxiter=50, iprint=2)
    balance_group.nonlinear_solver.options['solve_subsystems'] = True
    # prob.model.nonlinear_solver.linesearch = BoundsEnforceLS()
    balance_group.nonlinear_solver.options['atol'] = 1e-9

    prob.model.add_subsystem('thrust_balance_group',
                             balance_group,
                             promotes=['*'])

    prob.setup()
    prob.final_setup()

    # Calculate the induced axial velocity at the rotor for hover, used for
    # non-diminsionalation.
    rho = prob.get_val('rho', units='kg/m**3')[0]
    hub_diameter = prob.get_val('hub_diameter', units='m')[0]
    prop_diameter = prob.get_val('prop_diameter', units='m')[0]
    thrust_vtol = prob.get_val('thrust_vtol', units='N')[0]
    A_rotor = 0.25 * np.pi * (prop_diameter**2 - hub_diameter**2)
    v_h = np.sqrt(thrust_vtol / (2 * rho * A_rotor))

    # Climb:
    climb_velocity_nondim = np.linspace(0.1, 2., 10)
    induced_velocity_nondim = np.zeros_like(climb_velocity_nondim)
    for vc, vi in np.nditer([climb_velocity_nondim, induced_velocity_nondim],
                            op_flags=[['readonly'], ['writeonly']]):

        # Run the model with the requested climb velocity.
        prob.set_val('v', vc * v_h, units='m/s')
        print(f"v = {prob.get_val('v', units='m/s')}")
        prob.run_model()

        # Calculate the area-weighted average induced velocity at the rotor.
        # Need the area of each blade section.
        radii = prob.get_val('radii', units='m')
        dradii = prob.get_val('dradii', units='m')
        dArea = 2 * np.pi * radii * dradii

        # Get the induced velocity at the rotor plane for each blade section.
        Vx = prob.get_val('Vx', units='m/s')
        a = prob.get_val('ccblade_group.ccblade_comp.a')

        # Get the area-weighted average of the induced velocity.
        vi[...] = np.sum(a * Vx * dArea / A_rotor) / v_h

    # Induced velocity from plain old momentum theory (for climb).
    induced_velocity_mt = (-0.5 * climb_velocity_nondim +
                           np.sqrt((0.5 * climb_velocity_nondim)**2 + 1.))

    fig, ax = plt.subplots()
    ax.plot(climb_velocity_nondim,
            -induced_velocity_nondim,
            label='CCBlade.jl (climb)')
    ax.plot(climb_velocity_nondim,
            induced_velocity_mt,
            label='Momentum Theory (climb)')

    # Descent:
    # climb_velocity_nondim = np.linspace(-3.5, -2.6, 10)
    climb_velocity_nondim = np.linspace(-5.0, -2.1, 10)
    induced_velocity_nondim = np.zeros_like(climb_velocity_nondim)
    for vc, vi in np.nditer([climb_velocity_nondim, induced_velocity_nondim],
                            op_flags=[['readonly'], ['writeonly']]):

        # Run the model with the requested climb velocity.
        prob.set_val('v', vc * v_h, units='m/s')
        print(f"vc = {vc}, v = {prob.get_val('v', units='m/s')}")
        prob.run_model()

        # Calculate the area-weighted average induced velocity at the rotor.
        # Need the area of each blade section.
        radii = prob.get_val('radii', units='m')
        dradii = prob.get_val('dradii', units='m')
        dArea = 2 * np.pi * radii * dradii

        # Get the induced velocity at the rotor plane for each blade section.
        Vx = prob.get_val('Vx', units='m/s')
        a = prob.get_val('ccblade_group.ccblade_comp.a')

        # Get the area-weighted average of the induced velocity.
        vi[...] = np.sum(a * Vx * dArea / A_rotor) / v_h

    # Plot the induced velocity for descent.
    ax.plot(climb_velocity_nondim,
            -induced_velocity_nondim,
            label='CCBlade.jl (descent)')

    # Induced velocity from plain old momentum theory (for descent).
    induced_velocity_mt = (-0.5 * climb_velocity_nondim -
                           np.sqrt((0.5 * climb_velocity_nondim)**2 - 1.))
    ax.plot(climb_velocity_nondim,
            induced_velocity_mt,
            label='Momentum Theory (descent)')

    # Empirical region:
    climb_velocity_nondim = np.linspace(-1.9, -1.5, 5)
    induced_velocity_nondim = np.zeros_like(climb_velocity_nondim)
    for vc, vi in np.nditer([climb_velocity_nondim, induced_velocity_nondim],
                            op_flags=[['readonly'], ['writeonly']]):

        # Run the model with the requested climb velocity.
        prob.set_val('v', vc * v_h, units='m/s')
        print(f"vc = {vc}, v = {prob.get_val('v', units='m/s')}")
        prob.run_model()

        # Calculate the area-weighted average induced velocity at the rotor.
        # Need the area of each blade section.
        radii = prob.get_val('radii', units='m')
        dradii = prob.get_val('dradii', units='m')
        dArea = 2 * np.pi * radii * dradii

        # Get the induced velocity at the rotor plane for each blade section.
        Vx = prob.get_val('Vx', units='m/s')
        a = prob.get_val('ccblade_group.ccblade_comp.a')

        # Get the area-weighted average of the induced velocity.
        vi[...] = np.sum(a * Vx * dArea / A_rotor) / v_h

    # Plot the induced velocity for the empirical region.
    ax.plot(climb_velocity_nondim,
            -induced_velocity_nondim,
            label='CCBlade.jl (empirical region)')

    ax.set_xlabel('Vc/vh')
    ax.set_ylabel('Vi/vh')
    ax.legend()
    fig.savefig('induced_velocity.png')
Example #12
0
    def test_control_rate2_path_constraint_gl(self):
        from openmdao.api import Problem, Group, ScipyOptimizeDriver, DirectSolver
        from openmdao.utils.assert_utils import assert_rel_error
        from dymos import Phase, GaussLobatto
        from dymos.examples.brachistochrone.brachistochrone_ode import BrachistochroneODE

        p = Problem(model=Group())
        p.driver = ScipyOptimizeDriver()

        phase = Phase(ode_class=BrachistochroneODE,
                      transcription=GaussLobatto(num_segments=10, order=5))

        p.model.add_subsystem('phase0', phase)

        phase.set_time_options(initial_bounds=(0, 0), duration_bounds=(.5, 10))

        phase.set_state_options('x', fix_initial=True, fix_final=True)
        phase.set_state_options('y', fix_initial=True, fix_final=True)
        phase.set_state_options('v', fix_initial=True)

        phase.add_control('theta',
                          units='deg',
                          rate_continuity=False,
                          lower=0.01,
                          upper=179.9)

        phase.add_design_parameter('g', units='m/s**2', opt=False, val=9.80665)

        # Minimize time at the end of the phase
        phase.add_objective('time', loc='final', scaler=10)

        phase.add_path_constraint('theta_rate2',
                                  lower=-200,
                                  upper=200,
                                  units='rad/s**2')

        p.model.linear_solver = DirectSolver()
        p.model.options['assembled_jac_type'] = 'csc'

        p.setup()

        p['phase0.t_initial'] = 0.0
        p['phase0.t_duration'] = 2.0

        p['phase0.states:x'] = phase.interpolate(ys=[0, 10],
                                                 nodes='state_input')
        p['phase0.states:y'] = phase.interpolate(ys=[10, 5],
                                                 nodes='state_input')
        p['phase0.states:v'] = phase.interpolate(ys=[0, 9.9],
                                                 nodes='state_input')
        p['phase0.controls:theta'] = phase.interpolate(ys=[5, 100.5],
                                                       nodes='control_input')

        # Solve for the optimal trajectory
        p.run_driver()

        # Test the results
        assert_rel_error(self,
                         p.get_val('phase0.timeseries.time')[-1],
                         1.8016,
                         tolerance=1.0E-3)
    def test_brachistochrone_quick_start(self):
        import numpy as np
        from openmdao.api import Problem, Group, ScipyOptimizeDriver
        import dymos as dm
        import matplotlib
        matplotlib.use('Agg')
        import matplotlib.pyplot as plt

        #
        # Define the OpenMDAO problem
        #
        p = Problem(model=Group())

        #
        # Define a Trajectory object
        #
        traj = dm.Trajectory()

        p.model.add_subsystem('traj', subsys=traj)

        #
        # Define a Dymos Phase object with GaussLobatto Transcription
        #
        phase = dm.Phase(ode_class=BrachistochroneODE,
                         transcription=dm.GaussLobatto(num_segments=10, order=3))

        traj.add_phase(name='phase0', phase=phase)

        #
        # Set the time options
        # Time has no targets in our ODE.
        # We fix the initial time so that the it is not a design variable in the optimization.
        # The duration of the phase is allowed to be optimized, but is bounded on [0.5, 10].
        #
        phase.set_time_options(fix_initial=True, duration_bounds=(0.5, 10.0), units='s')

        #
        # Set the time options
        # Initial values of positions and velocity are all fixed.
        # The final value of position are fixed, but the final velocity is a free variable.
        # The equations of motion are not functions of position, so 'x' and 'y' have no targets.
        # The rate source points to the output in the ODE which provides the time derivative of the
        # given state.
        phase.set_state_options('x', fix_initial=True, fix_final=True, units='m', rate_source='xdot')
        phase.set_state_options('y', fix_initial=True, fix_final=True, units='m', rate_source='ydot')
        phase.set_state_options('v', fix_initial=True, fix_final=False, units='m/s',
                                rate_source='vdot', targets=['v'])

        # Define theta as a control.
        phase.add_control(name='theta', units='rad', lower=0, upper=np.pi, targets=['theta'])

        # Minimize final time.
        phase.add_objective('time', loc='final')

        # Set the driver.
        p.driver = ScipyOptimizeDriver()

        # Allow OpenMDAO to automatically determine our sparsity pattern.
        # Doing so can significant speed up the execution of Dymos.
        p.driver.options['dynamic_simul_derivs'] = True

        # Setup the problem
        p.setup(check=True)

        # Now that the OpenMDAO problem is setup, we can set the values of the states.
        p.set_val('traj.phase0.states:x',
                  phase.interpolate(ys=[0, 10], nodes='state_input'),
                  units='m')

        p.set_val('traj.phase0.states:y',
                  phase.interpolate(ys=[10, 5], nodes='state_input'),
                  units='m')

        p.set_val('traj.phase0.states:v',
                  phase.interpolate(ys=[0, 5], nodes='state_input'),
                  units='m/s')

        p.set_val('traj.phase0.controls:theta',
                  phase.interpolate(ys=[90, 90], nodes='control_input'),
                  units='deg')

        # Run the driver to solve the problem
        p.run_driver()

        # Check the validity of our results by using scipy.integrate.solve_ivp to
        # integrate the solution.
        sim_out = traj.simulate()

        # Plot the results
        fig, axes = plt.subplots(nrows=1, ncols=2, figsize=(12, 4.5))

        axes[0].plot(p.get_val('traj.phase0.timeseries.states:x'),
                     p.get_val('traj.phase0.timeseries.states:y'),
                     'ro', label='solution')

        axes[0].plot(sim_out.get_val('traj.phase0.timeseries.states:x'),
                     sim_out.get_val('traj.phase0.timeseries.states:y'),
                     'b-', label='simulation')

        axes[0].set_xlabel('x (m)')
        axes[0].set_ylabel('y (m/s)')
        axes[0].legend()
        axes[0].grid()

        axes[1].plot(p.get_val('traj.phase0.timeseries.time'),
                     p.get_val('traj.phase0.timeseries.controls:theta', units='deg'),
                     'ro', label='solution')

        axes[1].plot(sim_out.get_val('traj.phase0.timeseries.time'),
                     sim_out.get_val('traj.phase0.timeseries.controls:theta', units='deg'),
                     'b-', label='simulation')

        axes[1].set_xlabel('time (s)')
        axes[1].set_ylabel(r'$\theta$ (deg)')
        axes[1].legend()
        axes[1].grid()

        plt.show()
    def test_brachistochrone_vector_ode_path_constraints_radau_no_indices(
            self):

        p = Problem(model=Group())

        p.driver = ScipyOptimizeDriver()
        p.driver.options['dynamic_simul_derivs'] = True

        phase = Phase(ode_class=BrachistochroneVectorStatesODE,
                      transcription=Radau(num_segments=20, order=3))

        p.model.add_subsystem('phase0', phase)

        phase.set_time_options(fix_initial=True, duration_bounds=(.5, 10))

        phase.set_state_options('pos', fix_initial=True, fix_final=True)
        phase.set_state_options('v', fix_initial=True, fix_final=False)

        phase.add_control('theta',
                          continuity=True,
                          rate_continuity=True,
                          units='deg',
                          lower=0.01,
                          upper=179.9)

        phase.add_design_parameter('g', units='m/s**2', opt=False, val=9.80665)

        phase.add_path_constraint('pos_dot',
                                  shape=(2, ),
                                  units='m/s',
                                  lower=-4,
                                  upper=12)

        phase.add_timeseries_output('pos_dot', shape=(2, ), units='m/s')

        # Minimize time at the end of the phase
        phase.add_objective('time', loc='final', scaler=10)

        p.model.linear_solver = DirectSolver()
        p.setup(check=True, force_alloc_complex=True)

        p['phase0.t_initial'] = 0.0
        p['phase0.t_duration'] = 2.0

        pos0 = [0, 10]
        posf = [10, 5]

        p['phase0.states:pos'] = phase.interpolate(ys=[pos0, posf],
                                                   nodes='state_input')
        p['phase0.states:v'] = phase.interpolate(ys=[0, 9.9],
                                                 nodes='state_input')
        p['phase0.controls:theta'] = phase.interpolate(ys=[5, 100],
                                                       nodes='control_input')
        p['phase0.design_parameters:g'] = 9.80665

        p.run_driver()

        assert_rel_error(self,
                         np.min(p.get_val('phase0.timeseries.pos_dot')[:, -1]),
                         -4,
                         tolerance=1.0E-2)

        # Plot results
        if SHOW_PLOTS:
            exp_out = phase.simulate(times_per_seg=50)

            fig, ax = plt.subplots()
            fig.suptitle('Brachistochrone Solution')

            x_imp = p.get_val('phase0.timeseries.states:pos')[:, 0]
            y_imp = p.get_val('phase0.timeseries.states:pos')[:, 1]

            x_exp = exp_out.get_val('phase0.timeseries.states:pos')[:, 0]
            y_exp = exp_out.get_val('phase0.timeseries.states:pos')[:, 1]

            ax.plot(x_imp, y_imp, 'ro', label='implicit')
            ax.plot(x_exp, y_exp, 'b-', label='explicit')

            ax.set_xlabel('x (m)')
            ax.set_ylabel('y (m)')
            ax.grid(True)
            ax.legend(loc='upper right')

            fig, ax = plt.subplots()
            fig.suptitle('Brachistochrone Solution\nVelocity')

            t_imp = p.get_val('phase0.timeseries.time')
            t_exp = exp_out.get_val('phase0.timeseries.time')

            xdot_imp = p.get_val('phase0.timeseries.pos_dot')[:, 0]
            ydot_imp = p.get_val('phase0.timeseries.pos_dot')[:, 1]

            xdot_exp = exp_out.get_val('phase0.timeseries.pos_dot')[:, 0]
            ydot_exp = exp_out.get_val('phase0.timeseries.pos_dot')[:, 1]

            ax.plot(t_imp, xdot_imp, 'bo', label='implicit')
            ax.plot(t_exp, xdot_exp, 'b-', label='explicit')

            ax.plot(t_imp, ydot_imp, 'ro', label='implicit')
            ax.plot(t_exp, ydot_exp, 'r-', label='explicit')

            ax.set_xlabel('t (s)')
            ax.set_ylabel('v (m/s)')
            ax.grid(True)
            ax.legend(loc='upper right')

            fig, ax = plt.subplots()
            fig.suptitle('Brachistochrone Solution')

            x_imp = p.get_val('phase0.timeseries.time')
            y_imp = p.get_val('phase0.timeseries.control_rates:theta_rate2')

            x_exp = exp_out.get_val('phase0.timeseries.time')
            y_exp = exp_out.get_val(
                'phase0.timeseries.control_rates:theta_rate2')

            ax.plot(x_imp, y_imp, 'ro', label='implicit')
            ax.plot(x_exp, y_exp, 'b-', label='explicit')

            ax.set_xlabel('time (s)')
            ax.set_ylabel('theta rate2 (rad/s**2)')
            ax.grid(True)
            ax.legend(loc='lower right')

            plt.show()

        return p
Example #15
0
    def from_problem(
        cls,
        problem: om.Problem,
        use_initial_values: bool = False,
        get_promoted_names: bool = True,
        promoted_only: bool = True,
    ) -> "VariableList":
        """
        Creates a VariableList instance containing inputs and outputs of an OpenMDAO Problem.

        .. warning::

            problem.setup() must have been run.

        The inputs (is_input=True) correspond to the variables of IndepVarComp
        components and all the unconnected variables.

        .. note::

            Variables from _auto_ivc are ignored.

        :param problem: OpenMDAO Problem instance to inspect
        :param use_initial_values: if True, returned instance will contain values before computation
        :param get_promoted_names: if True, promoted names will be returned instead of absolute ones
                                   (if no promotion, absolute name will be returned)
        :param promoted_only: if True, only promoted variable names will be returned
        :return: VariableList instance
        """

        # Get inputs and outputs
        metadata_keys = (
            "value",
            "units",
            "shape",
            "size",
            "desc",
            "ref",
            "ref0",
            "lower",
            "upper",
            "tags",
        )
        inputs = problem.model.get_io_metadata("input",
                                               metadata_keys=metadata_keys)
        outputs = problem.model.get_io_metadata("output",
                                                metadata_keys=metadata_keys,
                                                excludes="_auto_ivc.*")
        indep_outputs = problem.model.get_io_metadata(
            "output",
            metadata_keys=metadata_keys,
            tags="indep_var",
            excludes="_auto_ivc.*")

        # Move outputs from IndepVarComps into inputs
        for abs_name, metadata in indep_outputs.items():
            del outputs[abs_name]
            inputs[abs_name] = metadata

        # Remove non-promoted variables if needed
        if promoted_only:
            inputs = {
                name: metadata
                for name, metadata in inputs.items()
                if "." not in metadata["prom_name"]
            }
            outputs = {
                name: metadata
                for name, metadata in outputs.items()
                if "." not in metadata["prom_name"]
            }

        # Add "is_input" field
        for metadata in inputs.values():
            metadata["is_input"] = True
        for metadata in outputs.values():
            metadata["is_input"] = False

        # Manage variable promotion
        if not get_promoted_names:
            final_inputs = inputs
            final_outputs = outputs
        else:
            promoted_outputs = {}
            for metadata in outputs.values():
                prom_name = metadata["prom_name"]
                # In case we get promoted names, several variables can match the same
                # promoted name, with possibly different declaration for default values.
                # We retain the first non-NaN value with defined units. If no units is
                # ever defined, the first non-NaN value is kept.
                # A non-NaN value with no units will be retained against a NaN value with
                # defined units.

                if prom_name in promoted_outputs:
                    # prom_name has already been encountered.
                    # Note: the succession of "if" is to help understanding, hopefully :)

                    if not np.all(
                            np.isnan(promoted_outputs[prom_name]["value"])):
                        if promoted_outputs[prom_name]["units"] is not None:
                            # We already have a non-NaN value with defined units for current
                            # promoted name. No need for using the current variable.
                            continue
                        if np.all(np.isnan(metadata["value"])):
                            # We already have a non-NaN value and current variable has a NaN value,
                            # so it can only add information about units. We keep the non-NaN value
                            continue

                    if (np.all(np.isnan(promoted_outputs[prom_name]["value"]))
                            and metadata["units"] is None):
                        # We already have a non-NaN value and current variable provides no unit.
                        # No need for using the current variable.
                        continue

                promoted_outputs[prom_name] = metadata

            # Remove from inputs the variables that are outputs of some other component
            promoted_inputs = {
                metadata["prom_name"]: dict(metadata, is_input=True)
                for metadata in inputs.values()
                if metadata["prom_name"] not in promoted_outputs
            }

            final_inputs = promoted_inputs
            final_outputs = promoted_outputs

        # Conversion to VariableList instances
        input_vars = VariableList.from_dict(final_inputs)
        output_vars = VariableList.from_dict(final_outputs)

        # Use computed value instead of initial ones, if asked for
        for variable in input_vars + output_vars:
            if not use_initial_values:
                try:
                    # Maybe useless, but we force units to ensure it is consistent
                    variable.value = problem.get_val(variable.name,
                                                     units=variable.units)
                except RuntimeError:
                    # In case problem is incompletely set, problem.get_val() will fail.
                    # In such case, falling back to the method for initial values
                    # should be enough.
                    pass

        return input_vars + output_vars
Example #16
0
    def test(self):
        """
        A simple example to illustrate usage of the concatenate/split components.

        Let's say we have two analysis tools which generate lists of test conditions to analyze.
        For this example, our two tools takeoff analysis and cruise analysis for an airplane.
        We'll generate altitudes and velocity vectors from two (fake) components, then combine them into one
        so we can feed a single vector to some other analysis tool.

        Once the tool is done, we'll split the results back out into takeoff and cruise phases.
        """
        import numpy as np
        from openmdao.api import Problem, Group, IndepVarComp
        from openmdao.utils.assert_utils import assert_rel_error
        from openconcept.utilities.math.combine_split_comp import VectorConcatenateComp, VectorSplitComp

        n_takeoff_pts = 3
        n_cruise_pts = 5

        p = Problem(model=Group())

        takeoff_conditions = IndepVarComp()
        takeoff_conditions.add_output(name='velocity',
                                      shape=(n_takeoff_pts, 2),
                                      units='m/s')
        takeoff_conditions.add_output(name='altitude',
                                      shape=(n_takeoff_pts, ),
                                      units='m')

        cruise_conditions = IndepVarComp()
        cruise_conditions.add_output(name='velocity',
                                     shape=(n_cruise_pts, 2),
                                     units='m/s')
        cruise_conditions.add_output(name='altitude',
                                     shape=(n_cruise_pts, ),
                                     units='m')

        p.model.add_subsystem(name='takeoff_conditions',
                              subsys=takeoff_conditions)
        p.model.add_subsystem(name='cruise_conditions',
                              subsys=cruise_conditions)

        combiner = p.model.add_subsystem(name='combiner',
                                         subsys=VectorConcatenateComp())

        combiner.add_relation('velocity', ['to_vel', 'cruise_vel'],
                              vec_sizes=[3, 5],
                              length=2,
                              units='m/s')

        combiner.add_relation('altitude', ['to_alt', 'cruise_alt'],
                              vec_sizes=[3, 5],
                              units='m')

        p.model.connect('takeoff_conditions.velocity', 'combiner.to_vel')
        p.model.connect('cruise_conditions.velocity', 'combiner.cruise_vel')
        p.model.connect('takeoff_conditions.altitude', 'combiner.to_alt')
        p.model.connect('cruise_conditions.altitude', 'combiner.cruise_alt')

        divider = p.model.add_subsystem(name='divider',
                                        subsys=VectorSplitComp())
        divider.add_relation(['to_vel', 'cruise_vel'],
                             'velocity',
                             vec_sizes=[3, 5],
                             length=2,
                             units='m/s')
        p.model.connect('combiner.velocity', 'divider.velocity')

        p.setup()

        #set thrust to exceed drag, weight to equal lift for this scenario
        p['takeoff_conditions.velocity'][:, 0] = [30, 40, 50]
        p['takeoff_conditions.velocity'][:, 1] = [0, 0, 0]
        p['cruise_conditions.velocity'][:, 0] = [60, 60, 60, 60, 60]
        p['cruise_conditions.velocity'][:, 1] = [5, 0, 0, 0, -5]
        p['takeoff_conditions.altitude'][:] = [0, 0, 0]
        p['cruise_conditions.altitude'][:] = [6000, 7500, 8000, 8500, 5000]

        p.run_model()

        # Verify the results
        expected_vel = np.array([[30, 0], [40, 0], [50, 0], [60, 5], [60, 0],
                                 [60, 0], [60, 0], [60, -5]])
        expected_alt = np.array([0, 0, 0, 6000, 7500, 8000, 8500, 5000])
        expected_split_vel = np.array([[60, 5], [60, 0], [60, 0], [60, 0],
                                       [60, -5]])
        assert_rel_error(self, p.get_val('combiner.velocity', units='m/s'),
                         expected_vel)
        assert_rel_error(self, p.get_val('combiner.altitude', units='m'),
                         expected_alt)
        assert_rel_error(self, p.get_val('divider.cruise_vel', units='m/s'),
                         expected_split_vel)
p['traj.phase0.states:m'] = phase.interpolate(ys=[19030.468, 10000.], nodes='state_input')
# p['traj.phase0.controls:alpha'] = phase.interpolate(ys=[0.0, 0.0], nodes='control_input')

p['traj.phase0.polynomial_controls:alpha'] = np.array([[4.86918595],
                                                        [1.30322324],
                                                        [1.41897019],
                                                        [1.10227365],
                                                        [3.58780732],
                                                        [5.36233472]])
p['traj.phase0.t_duration'] = 346.13171325
#
# Solve for the optimal trajectory
#
# p.run_model()
p.run_driver()
print(p.get_val('traj.phase0.t_duration')[0])
# print(p.get_val('traj.phase0.rhs_all.atmos.rho'))
# p.run_model()
# totals = p.compute_totals(of=['traj.phase0.states:m'], wrt=['traj.phase0.timeseries.controls:alpha'])
# print(totals['traj.phase0.states:m', 'traj.phase0.timeseries.controls:alpha'])
#
# Test the results
#
# print(p.driver.get_constraint_values().keys())


# print('len m = ', p.driver.get_constraint_values()['traj.phases.phase0.collocation_constraint.defects:m'].size)
# print('len gamma = ', p.driver.get_constraint_values()['traj.phases.phase0.collocation_constraint.defects:gam'].size)
# print('len v = ', p.driver.get_constraint_values()['traj.phases.phase0.collocation_constraint.defects:v'].size)
# print('len h = ', p.driver.get_constraint_values()['traj.phases.phase0.collocation_constraint.defects:h'].size)
# print('len r = ', p.driver.get_constraint_values()['traj.phases.phase0.collocation_constraint.defects:r'].size)
Example #18
0
        J['mass_wick',
          'cu_density'] = L_heatpipe * fill_wk * np.pi * ((D_v / 2 + t_wk)**2 -
                                                          (D_v / 2)**2)
        J['mass_wick',
          'fill_wk'] = L_heatpipe * cu_density * np.pi * ((D_v / 2 + t_wk)**2 -
                                                          (D_v / 2)**2)
        J['mass_wick',
          't_wk'] = L_heatpipe * cu_density * fill_wk * np.pi * 2 * (D_v / 2 +
                                                                     t_wk)
        J['mass_wick', 'D_v'] = L_heatpipe * cu_density * fill_wk * np.pi * (
            (D_v / 2 + t_wk) - (D_v / 2))


if __name__ == "__main__":
    from openmdao.api import Problem

    nn = 1
    prob = Problem()

    prob.model.add_subsystem('hp_mass',
                             heatPipeMass(num_nodes=nn),
                             promotes=['*'])

    prob.setup(force_alloc_complex=True)
    prob.run_model()
    prob.check_partials(method='cs', compact_print=True)

    print('mass_heatpipe = ', prob.get_val('hp_mass.mass_heatpipe'))
    print('mass_liquid = ', prob.get_val('hp_mass.mass_liquid'))
    print('mass_wick = ', prob.get_val('hp_mass.mass_wick'))
Example #19
0
        des_vars.add_output('cp_cell', val=1020., units='J/(kg*K)')
        des_vars.add_output('cp_case', val=921., units='J/(kg*K)')
        des_vars.add_output('volume_{cell}', val=1.125, units='inch**3')

        self.add_subsystem(name='BatteryStatics', subsys=BatteryStatics(), promotes=['*'])


if __name__ == '__main__':
    from openmdao.api import Problem, Group, IndepVarComp

    p = Problem()
    p.model = Group()
    des_vars = p.model.add_subsystem('des_vars', IndepVarComp(), promotes=['*'])

    des_vars.add_output('V_{batt}', 500., units='V')
    des_vars.add_output('I_{batt}', 300., units='A')
    des_vars.add_output('mass_{cell}', 0.045, units='kg')

    p.model.add_subsystem('mass', BatteryStatics(), promotes=['*'])

    p.setup(check=False, force_alloc_complex=True)
    p.check_partials(compact_print=True, method='cs')
    
    p.setup()
    p.run_model()

    print('Num series:  ', p.get_val('n_{series}'))
    print('Num parallel:  ', p.get_val('n_{parallel}'))
    print('Num parallel:  ', p.get_val('n_{parallel}2'))
    print('Battery Mass:  ', p.get_val('mass_{battery}'))
    print('Battery Nominal Energy:  ', p.get_val('nominal_energy'))
Example #20
0
    def test_brachistochrone_for_docs_runge_kutta_polynomial_controls(self):
        from openmdao.api import Problem, Group, ScipyOptimizeDriver, DirectSolver, SqliteRecorder
        from openmdao.utils.assert_utils import assert_rel_error
        import dymos as dm
        from dymos.examples.plotting import plot_results
        from dymos.examples.brachistochrone import BrachistochroneODE

        #
        # Initialize the Problem and the optimization driver
        #
        p = Problem(model=Group())
        p.driver = ScipyOptimizeDriver()
        p.driver.options['dynamic_simul_derivs'] = True

        #
        # Create a trajectory and add a phase to it
        #
        traj = p.model.add_subsystem('traj', dm.Trajectory())

        phase = traj.add_phase(
            'phase0',
            dm.Phase(ode_class=BrachistochroneODE,
                     transcription=dm.RungeKutta(num_segments=10)))

        #
        # Set the variables
        #
        phase.set_time_options(initial_bounds=(0, 0), duration_bounds=(.5, 10))
        phase.set_state_options('x', fix_initial=True)
        phase.set_state_options('y', fix_initial=True)
        phase.set_state_options('v', fix_initial=True)
        phase.add_polynomial_control('theta',
                                     units='deg',
                                     lower=0.01,
                                     upper=179.9,
                                     order=1)
        phase.add_design_parameter('g', units='m/s**2', opt=False, val=9.80665)

        #
        # Final state values are not optimization variables, so we must enforce final values
        # with boundary constraints, not simple bounds.
        #
        phase.add_boundary_constraint('x', loc='final', equals=10)
        phase.add_boundary_constraint('y', loc='final', equals=5)

        #
        # Minimize time at the end of the phase
        #
        phase.add_objective('time', loc='final', scaler=10)

        p.model.linear_solver = DirectSolver()

        #
        # Setup the Problem
        #
        p.setup()

        #
        # Set the initial values
        #
        p['traj.phase0.t_initial'] = 0.0
        p['traj.phase0.t_duration'] = 2.0

        p['traj.phase0.states:x'] = phase.interpolate(ys=[0, 10],
                                                      nodes='state_input')
        p['traj.phase0.states:y'] = phase.interpolate(ys=[10, 5],
                                                      nodes='state_input')
        p['traj.phase0.states:v'] = phase.interpolate(ys=[0, 9.9],
                                                      nodes='state_input')
        p['traj.phase0.polynomial_controls:theta'][:] = 5.0

        #
        # Solve for the optimal trajectory
        #
        p.run_driver()

        # Test the results
        assert_rel_error(self,
                         p.get_val('traj.phase0.timeseries.time')[-1],
                         1.8016,
                         tolerance=1.0E-3)

        # Generate the explicitly simulated trajectory
        exp_out = traj.simulate()

        plot_results(
            [('traj.phase0.timeseries.states:x',
              'traj.phase0.timeseries.states:y', 'x (m)', 'y (m)'),
             ('traj.phase0.timeseries.time',
              'traj.phase0.timeseries.polynomial_controls:theta', 'time (s)',
              'theta (deg)')],
            title=
            'Brachistochrone Solution\nRK4 Shooting and Polynomial Controls',
            p_sol=p,
            p_sim=exp_out)

        plt.show()
Example #21
0
    import matplotlib.pyplot as plt
    plt.figure()
    plt.plot(t, prob['component.T'] - 273.15)
    plt.xlabel('time (min)')
    plt.ylabel('motor temp (C)')
    plt.figure()
    plt.plot(prob['fltcond|h'], prob['component.T'] - 273.15)
    plt.xlabel('altitude (ft)')
    plt.ylabel('motor temp (C)')
    plt.figure()
    plt.plot(t, prob['duct.inlet.M'])
    plt.xlabel('Mach number')
    plt.ylabel('steady state motor temp (C)')
    plt.figure()
    plt.plot(prob['duct.inlet.M'], prob['duct.force.F_net'])
    plt.xlabel('M_inf')
    plt.ylabel('drag N')
    plt.figure()
    plt.plot(
        prob['duct.inlet.M'], prob['duct.mdot'] / prob['atmos.fltcond|rho'] /
        prob.get_val('atmos.fltcond|Utrue', units='m/s') /
        prob.get_val('duct.area_nozzle', units='m**2'))
    plt.xlabel('M_inf')
    plt.ylabel('mdot / rho / U / A_nozzle')
    plt.figure()
    plt.plot(prob['duct.inlet.M'], prob['duct.nozzle.M'])
    plt.xlabel('M_inf')
    # plt.ylabel('M_nozzle')
    plt.show()
Example #22
0
        J['A_interc', 'D_v'] = np.pi*L_cond
        J['A_interc', 'L_cond'] = np.pi*D_v

        J['A_intere', 'D_v'] = np.pi*L_evap
        J['A_intere', 'L_evap'] = np.pi*D_v


# # ------------ Derivative Checks --------------- #
if __name__ == "__main__":
    from openmdao.api import Problem

    nn = 1
    prob = Problem()

    prob.model.add_subsystem('comp1', SizeGroup(num_nodes=nn), promotes=['*'])

    prob.setup(force_alloc_complex=True)
    prob.run_model()
    prob.check_partials(method='cs', compact_print=True)


    print('A_w = ', prob.get_val('comp1.A_w'))
    print('A_wk = ', prob.get_val('comp1.A_wk'))
    print('A_interc = ', prob.get_val('comp1.A_interc'))
    print('A_intere = ', prob.get_val('comp1.A_intere'))

    print('r_i', prob.get_val('comp1.r_i'))
    print('A_cond', prob.get_val('comp1.A_cond'))
    print('A_evap', prob.get_val('comp1.A_evap'))
    print('L_eff', prob.get_val('comp1.L_eff'))
    def test_min_time_climb_for_docs_gauss_lobatto(self):
        import matplotlib.pyplot as plt

        from openmdao.api import Problem, Group, pyOptSparseDriver, DirectSolver
        from openmdao.utils.assert_utils import assert_rel_error

        import dymos as dm
        from dymos.examples.min_time_climb.min_time_climb_ode import MinTimeClimbODE
        from dymos.examples.plotting import plot_results

        #
        # Instantiate the problem and configure the optimization driver
        #
        p = Problem(model=Group())

        p.driver = pyOptSparseDriver()
        p.driver.options['optimizer'] = 'SLSQP'
        p.driver.options['dynamic_simul_derivs'] = True

        #
        # Instantiate the trajectory and phase
        #
        traj = dm.Trajectory()

        phase = dm.Phase(ode_class=MinTimeClimbODE,
                         transcription=dm.GaussLobatto(num_segments=20,
                                                       compressed=True))

        traj.add_phase('phase0', phase)

        p.model.add_subsystem('traj', traj)

        #
        # Set the options on the optimization variables
        #
        phase.set_time_options(fix_initial=True,
                               duration_bounds=(50, 400),
                               duration_ref=100.0)

        phase.set_state_options('r',
                                fix_initial=True,
                                lower=0,
                                upper=1.0E6,
                                ref=1.0E3,
                                defect_ref=1.0E3,
                                units='m')

        phase.set_state_options('h',
                                fix_initial=True,
                                lower=0,
                                upper=20000.0,
                                ref=1.0E2,
                                defect_ref=1.0E2,
                                units='m')

        phase.set_state_options('v',
                                fix_initial=True,
                                lower=10.0,
                                ref=1.0E2,
                                defect_ref=1.0E2,
                                units='m/s')

        phase.set_state_options('gam',
                                fix_initial=True,
                                lower=-1.5,
                                upper=1.5,
                                ref=1.0,
                                defect_scaler=1.0,
                                units='rad')

        phase.set_state_options('m',
                                fix_initial=True,
                                lower=10.0,
                                upper=1.0E5,
                                ref=1.0E3,
                                defect_ref=1.0E3)

        phase.add_control('alpha',
                          units='deg',
                          lower=-8.0,
                          upper=8.0,
                          scaler=1.0,
                          rate_continuity=True,
                          rate_continuity_scaler=100.0,
                          rate2_continuity=False)

        phase.add_design_parameter('S', val=49.2386, units='m**2', opt=False)
        phase.add_design_parameter('Isp', val=1600.0, units='s', opt=False)
        phase.add_design_parameter('throttle', val=1.0, opt=False)

        #
        # Setup the boundary and path constraints
        #
        phase.add_boundary_constraint('h',
                                      loc='final',
                                      equals=20000,
                                      scaler=1.0E-3,
                                      units='m')
        phase.add_boundary_constraint('aero.mach',
                                      loc='final',
                                      equals=1.0,
                                      shape=(1, ))
        phase.add_boundary_constraint('gam',
                                      loc='final',
                                      equals=0.0,
                                      units='rad')

        phase.add_path_constraint(name='h',
                                  lower=100.0,
                                  upper=20000,
                                  ref=20000)
        phase.add_path_constraint(name='aero.mach',
                                  lower=0.1,
                                  upper=1.8,
                                  shape=(1, ))

        # Minimize time at the end of the phase
        phase.add_objective('time', loc='final', ref=1.0)

        p.model.linear_solver = DirectSolver()

        #
        # Setup the problem and set the initial guess
        #
        p.setup(check=True)

        p['traj.phase0.t_initial'] = 0.0
        p['traj.phase0.t_duration'] = 500

        p['traj.phase0.states:r'] = phase.interpolate(ys=[0.0, 50000.0],
                                                      nodes='state_input')
        p['traj.phase0.states:h'] = phase.interpolate(ys=[100.0, 20000.0],
                                                      nodes='state_input')
        p['traj.phase0.states:v'] = phase.interpolate(ys=[135.964, 283.159],
                                                      nodes='state_input')
        p['traj.phase0.states:gam'] = phase.interpolate(ys=[0.0, 0.0],
                                                        nodes='state_input')
        p['traj.phase0.states:m'] = phase.interpolate(ys=[19030.468, 10000.],
                                                      nodes='state_input')
        p['traj.phase0.controls:alpha'] = phase.interpolate(
            ys=[0.0, 0.0], nodes='control_input')

        #
        # Solve for the optimal trajectory
        #
        p.run_driver()

        #
        # Test the results
        #
        assert_rel_error(self,
                         p.get_val('traj.phase0.t_duration'),
                         321.0,
                         tolerance=1.0E-1)

        #
        # Get the explicitly simulated solution and plot the results
        #
        exp_out = traj.simulate()

        plot_results(
            [('traj.phase0.timeseries.time', 'traj.phase0.timeseries.states:h',
              'time (s)', 'altitude (m)'),
             ('traj.phase0.timeseries.time',
              'traj.phase0.timeseries.controls:alpha', 'time (s)',
              'alpha (deg)')],
            title='Supersonic Minimum Time-to-Climb Solution',
            p_sol=p,
            p_sim=exp_out)

        plt.show()
Example #24
0
    def from_problem(
        cls,
        problem: om.Problem,
        use_initial_values: bool = False,
        promoted_only=True,
    ) -> "VariableList":
        """
        Creates a VariableList instance containing
        variables (inputs and outputs) of a an OpenMDAO Problem.
        The inputs (is_input=True) correspond to the variables of IndepVarComp
        components and all the unconnected variables.

        If variables are promoted, the promoted name will be used. Otherwise ( and if
        promoted_only is False), the absolute name will be used.

        :param problem: OpenMDAO Problem instance to inspect
        :param use_initial_values: if True, returned instance will contain values before computation
        :param promoted_only: if True, non-promoted variables will be excluded
        :return: VariableList instance
        """
        variables = VariableList()

        # Setup() is needed
        problem = get_problem_after_setup(problem)
        model = problem.model

        # Determining global inputs

        # from unconnected inputs
        mandatory_unconnected, optional_unconnected = get_unconnected_input_names(
            problem)
        unconnected_abs_names = mandatory_unconnected + optional_unconnected

        unconnected_inputs = []
        for abs_name in unconnected_abs_names:
            unconnected_inputs.append(model._var_abs2prom["input"][abs_name])

        # from ivc outputs
        ivc_inputs = []
        for subsystem in model.system_iter():
            if isinstance(subsystem, om.IndepVarComp):
                input_variables = cls.from_ivc(subsystem)
                for var in input_variables:
                    ivc_inputs.append(var.name)

        global_inputs = unconnected_inputs + ivc_inputs

        prom2abs = {}
        prom2abs.update(model._var_allprocs_prom2abs_list["input"])
        prom2abs.update(model._var_allprocs_prom2abs_list["output"])

        for prom_name, abs_names in prom2abs.items():
            if not promoted_only or "." not in prom_name:
                # Pick the first
                abs_name = abs_names[0]
                metadata = deepcopy(model._var_abs2meta[abs_name])

                # Setting type (IN or OUT)
                if prom_name in global_inputs:
                    metadata.update({"is_input": True})
                else:
                    metadata.update({"is_input": False})

                variable = Variable(name=prom_name, **metadata)
                if not use_initial_values:
                    try:
                        # Maybe useless, but we force units to ensure it is consistent
                        variable.value = problem.get_val(prom_name,
                                                         units=variable.units)
                    except RuntimeError:
                        # In case problem is incompletely set, problem.get_val() will fail.
                        # In such case, falling back to the method for initial values
                        # should be enough.
                        pass
                variables.append(variable)

        return variables
Example #25
0
driverRecorder = om.SqliteRecorder('GA/driverRecorder.sql')
problemRecorder = om.SqliteRecorder('GA/problemRecorder.sql')

openMDAOProblem.driver.add_recorder(driverRecorder)
openMDAOProblem.driver.add_recorder(problemRecorder)

# Setup and run
openMDAOProblem.setup()

openMDAOProblem.set_val('dv_Gap.gap',                1.0)
openMDAOProblem.set_val('dv_Stagger.stagger',        1.0)
openMDAOProblem.set_val('dv_StaggerRow.stagger_row', 0.0)
openMDAOProblem.set_val("dv_afCol.af_col",           1.0)
openMDAOProblem.set_val("dv_afRow.af_row",           1.0)
openMDAOProblem.set_val("dv_aspect.aspect",          8.0)

openMDAOProblem.run_driver()

print("Aero Properties:")
print('CL: ', openMDAOProblem.get_val('AVL.CLtot'))
print('CDi: ', openMDAOProblem.get_val('AVL.CDtot'))
print('CDf: ', openMDAOProblem.get_val('Friction.CDtotal'))

print('Design Variables:')
print('Gap: ', openMDAOProblem.get_val('dv_Gap.gap'))
print('Stagger: ', openMDAOProblem.get_val('dv_Stagger.stagger'))
print('Stagger Row: ', openMDAOProblem.get_val('dv_StaggerRow.stagger_row'))

myProblem.closeCAPS()
Example #26
0
    # print some outputs
    vars_list = [
        'ac|weights|MTOW', 'descent.propmodel.batt1.SOC_final',
        'rotate.range_final'
    ]
    units = ['lb', None, 'ft']
    nice_print_names = [
        'MTOW', 'Final battery state of charge', 'TOFL (over 35ft obstacle)'
    ]
    print(
        "======================================================================="
    )
    for i, thing in enumerate(vars_list):
        print(nice_print_names[i] + ': ' +
              str(prob.get_val(thing, units=units[i])[0]) + ' ' +
              str(units[i]))

        y_variables = [
            'fltcond|h', 'fltcond|Ueas', 'throttle', 'fltcond|vs',
            'propmodel.batt1.SOC', 'propmodel.motorheatsink.T',
            'propmodel.reservoir.T_out', 'propmodel.duct.mdot'
        ]
        y_units = ['ft', 'kn', None, 'ft/min', None, 'degC', 'degC', 'kg/s']

    # plot some stuff
    plots = True
    if plots:
        x_var = 'range'
        x_unit = 'ft'
        y_vars = [
Example #27
0
    def test_brachistochrone_base_phase_class_gl(self):
        from openmdao.api import Problem, Group, ScipyOptimizeDriver, DirectSolver
        from openmdao.utils.assert_utils import assert_rel_error
        from dymos import Phase, GaussLobatto

        class BrachistochronePhase(Phase):
            def setup(self):

                self.options['ode_class'] = BrachistochroneODE
                self.set_time_options(initial_bounds=(0, 0),
                                      duration_bounds=(.5, 10),
                                      units='s')
                self.set_state_options('x',
                                       fix_initial=True,
                                       rate_source='xdot',
                                       units='m')
                self.set_state_options('y',
                                       fix_initial=True,
                                       rate_source='ydot',
                                       units='m')
                self.set_state_options('v',
                                       fix_initial=True,
                                       rate_source='vdot',
                                       targets=['v'],
                                       units='m/s')
                self.add_control('theta',
                                 units='deg',
                                 rate_continuity=False,
                                 lower=0.01,
                                 upper=179.9,
                                 targets=['theta'])
                self.add_design_parameter('g',
                                          units='m/s**2',
                                          opt=False,
                                          val=9.80665,
                                          targets=['g'])

                super(BrachistochronePhase, self).setup()

        p = Problem(model=Group())
        p.driver = ScipyOptimizeDriver()

        phase = BrachistochronePhase(
            transcription=GaussLobatto(num_segments=20, order=3))
        p.model.add_subsystem('phase0', phase)

        phase.add_boundary_constraint('x', loc='final', equals=10)
        phase.add_boundary_constraint('y', loc='final', equals=5)

        # Minimize time at the end of the phase
        phase.add_objective('time', loc='final', scaler=10)

        p.model.linear_solver = DirectSolver()

        p.setup()

        p['phase0.t_initial'] = 0.0
        p['phase0.t_duration'] = 2.0

        p['phase0.states:x'] = phase.interpolate(ys=[0, 10],
                                                 nodes='state_input')
        p['phase0.states:y'] = phase.interpolate(ys=[10, 5],
                                                 nodes='state_input')
        p['phase0.states:v'] = phase.interpolate(ys=[0, 9.9],
                                                 nodes='state_input')
        p['phase0.controls:theta'] = phase.interpolate(ys=[5, 100.5],
                                                       nodes='control_input')

        # Solve for the optimal trajectory
        p.run_driver()

        # Test the results
        assert_rel_error(self,
                         p.get_val('phase0.timeseries.time')[-1],
                         1.8016,
                         tolerance=1.0E-3)

        exp_out = phase.simulate()

        assert_rel_error(self,
                         exp_out.get_val('phase0.timeseries.states:x')[-1],
                         10,
                         tolerance=1.0E-3)
        assert_rel_error(self,
                         exp_out.get_val('phase0.timeseries.states:y')[-1],
                         5,
                         tolerance=1.0E-3)
Example #28
0
        T_hp = inputs['T_hp']
        h_fg = inputs['h_fg']
        P_v = inputs['P_v']
        rho_v = inputs['rho_v']
        r_h = inputs['XS:r_h']

        R_v = L_eff * 8 * R_g * mu_v * T_hp ** 2 / (np.pi * h_fg ** 2 * P_v * rho_v * (r_h ** 4))

        J['R_v', 'LW:L_eff'] = R_v / L_eff
        J['R_v', 'R_g'] = R_v / R_g
        J['R_v', 'mu_v'] = R_v / mu_v
        J['R_v', 'T_hp'] = 2 * R_v / T_hp
        J['R_v', 'h_fg'] = -2 * R_v / h_fg
        J['R_v', 'P_v'] = -R_v / P_v
        J['R_v', 'rho_v'] = -R_v / rho_v
        J['R_v', 'XS:r_h'] = -4 * R_v / r_h

# # ------------ Derivative Checks --------------- #
if __name__ == '__main__':
    from openmdao.api import Problem

    nn = 1

    prob = Problem()
    prob.model.add_subsystem('comp1', AxialThermalResistance(num_nodes=nn), promotes_outputs=['*'], promotes_inputs=['*'])
    prob.setup(force_alloc_complex=True)
    prob.run_model()
    prob.check_partials(method='cs', compact_print=True)

    print('R_aw = ', prob.get_val('comp1.R_aw'))
    print('R_awk = ', prob.get_val('comp1.R_awk'))
Example #29
0
    def test_brachistochrone_forward_shooting_boundary_constrained_design_parameter(self):
        from openmdao.api import Problem, Group, ScipyOptimizeDriver, DirectSolver
        from openmdao.utils.assert_utils import assert_rel_error
        from dymos import Phase, RungeKutta
        from dymos.examples.brachistochrone.brachistochrone_ode import BrachistochroneODE

        p = Problem(model=Group())
        p.driver = ScipyOptimizeDriver()
        p.driver.options['dynamic_simul_derivs'] = True

        phase = Phase(ode_class=BrachistochroneODE,
                      transcription=RungeKutta(num_segments=20))

        p.model.add_subsystem('phase0', phase)

        phase.set_time_options(initial_bounds=(0, 0), duration_bounds=(0.5, 2.0))

        phase.set_state_options('x', fix_initial=True)
        phase.set_state_options('y', fix_initial=True)
        phase.set_state_options('v', fix_initial=True)

        phase.add_polynomial_control('theta', order=2, units='deg', lower=0.01, upper=179.9)
        phase.add_design_parameter('g', units='m/s**2', opt=False, val=9.80665)

        # Final state values can't be controlled with simple bounds in RungeKuttaPhase,
        # so use nonlinear boundary constraints instead.
        phase.add_boundary_constraint('x', loc='final', equals=10)
        phase.add_boundary_constraint('y', loc='final', equals=5)
        phase.add_boundary_constraint('theta_rate2', loc='final', equals=0)

        # Minimize time at the end of the phase
        phase.add_objective('time_phase', loc='final', scaler=1)

        p.model.linear_solver = DirectSolver()

        p.setup(check=True)

        p['phase0.t_initial'] = 0.0
        p['phase0.t_duration'] = 2.0

        p['phase0.states:x'] = 0
        p['phase0.states:y'] = 10
        p['phase0.states:v'] = 0
        p['phase0.polynomial_controls:theta'][:, 0] = [0.01, 50, 100]

        # Solve for the optimal trajectory
        p.run_driver()

        # Test the results
        assert_rel_error(self, p['phase0.time'][-1], 1.8016, tolerance=1.0E-3)

        assert_rel_error(self,
                         p.get_val('phase0.timeseries.polynomial_control_rates:theta_rate2')[-1, 0],
                         0.0,
                         tolerance=1.0E-9)

        # Generate the explicitly simulated trajectory
        exp_out = phase.simulate()

        assert_rel_error(self, exp_out.get_val('phase0.timeseries.states:x')[-1, 0], 10,
                         tolerance=1.0E-3)
        assert_rel_error(self, exp_out.get_val('phase0.timeseries.states:y')[-1, 0], 5,
                         tolerance=1.0E-3)
Example #30
0
    def test_steady_aircraft_for_docs(self):
        import matplotlib.pyplot as plt

        from openmdao.api import Problem, Group, pyOptSparseDriver, IndepVarComp
        from openmdao.utils.assert_utils import assert_rel_error

        import dymos as dm

        from dymos.examples.aircraft_steady_flight.aircraft_ode import AircraftODE
        from dymos.examples.plotting import plot_results
        from dymos.utils.lgl import lgl

        p = Problem(model=Group())
        p.driver = pyOptSparseDriver()
        p.driver.options['optimizer'] = 'SLSQP'
        p.driver.options['dynamic_simul_derivs'] = True

        num_seg = 15
        seg_ends, _ = lgl(num_seg + 1)

        traj = p.model.add_subsystem('traj', dm.Trajectory())

        phase = traj.add_phase(
            'phase0',
            dm.Phase(ode_class=AircraftODE,
                     transcription=dm.Radau(num_segments=num_seg,
                                            segment_ends=seg_ends,
                                            order=3,
                                            compressed=False)))

        # Pass Reference Area from an external source
        assumptions = p.model.add_subsystem('assumptions', IndepVarComp())
        assumptions.add_output('S', val=427.8, units='m**2')
        assumptions.add_output('mass_empty', val=1.0, units='kg')
        assumptions.add_output('mass_payload', val=1.0, units='kg')

        phase.set_time_options(initial_bounds=(0, 0),
                               duration_bounds=(300, 10000),
                               duration_ref=5600)

        phase.set_state_options('range',
                                units='NM',
                                fix_initial=True,
                                fix_final=False,
                                ref=1e-3,
                                defect_ref=1e-3,
                                lower=0,
                                upper=2000)
        phase.set_state_options('mass_fuel',
                                units='lbm',
                                fix_initial=True,
                                fix_final=True,
                                upper=1.5E5,
                                lower=0.0,
                                ref=1e2,
                                defect_ref=1e2)
        phase.set_state_options('alt',
                                units='kft',
                                fix_initial=True,
                                fix_final=True,
                                lower=0.0,
                                upper=60,
                                ref=1e-3,
                                defect_ref=1e-3)

        phase.add_control('climb_rate',
                          units='ft/min',
                          opt=True,
                          lower=-3000,
                          upper=3000,
                          rate_continuity=True,
                          rate2_continuity=False)

        phase.add_control('mach', units=None, opt=False)

        phase.add_input_parameter('S', units='m**2')
        phase.add_input_parameter('mass_empty', units='kg')
        phase.add_input_parameter('mass_payload', units='kg')

        phase.add_path_constraint('propulsion.tau',
                                  lower=0.01,
                                  upper=2.0,
                                  shape=(1, ))

        p.model.connect('assumptions.S', 'traj.phase0.input_parameters:S')
        p.model.connect('assumptions.mass_empty',
                        'traj.phase0.input_parameters:mass_empty')
        p.model.connect('assumptions.mass_payload',
                        'traj.phase0.input_parameters:mass_payload')

        phase.add_objective('range', loc='final', ref=-1.0e-4)

        p.setup()

        p['traj.phase0.t_initial'] = 0.0
        p['traj.phase0.t_duration'] = 3600.0
        p['traj.phase0.states:range'][:] = phase.interpolate(
            ys=(0, 724.0), nodes='state_input')
        p['traj.phase0.states:mass_fuel'][:] = phase.interpolate(
            ys=(30000, 1e-3), nodes='state_input')
        p['traj.phase0.states:alt'][:] = 10.0

        p['traj.phase0.controls:mach'][:] = 0.8

        p['assumptions.S'] = 427.8
        p['assumptions.mass_empty'] = 0.15E6
        p['assumptions.mass_payload'] = 84.02869 * 400

        p.run_driver()

        assert_rel_error(self,
                         p.get_val('traj.phase0.timeseries.states:range',
                                   units='NM')[-1],
                         726.85,
                         tolerance=1.0E-2)

        exp_out = traj.simulate()

        plot_results([('traj.phase0.timeseries.states:range',
                       'traj.phase0.timeseries.states:alt', 'range (NM)',
                       'altitude (kft)'),
                      ('traj.phase0.timeseries.time',
                       'traj.phase0.timeseries.states:mass_fuel', 'time (s)',
                       'fuel mass (lbm)')],
                     title='Commercial Aircraft Optimization',
                     p_sol=p,
                     p_sim=exp_out)

        plt.show()
Example #31
0
        'ft**2', 'kn', 'kn', 'deg', 'inch**2', 'lbf', 'lb', 'lb/s'
    ]
    nice_print_names = [
        'MTOW', 'OEW', 'Fuel used', 'TOFL (over 35ft obstacle)',
        'Final state of charge', 'Cruise hybridization', 'Battery weight',
        'MTOW margin', 'Motor rating', 'Generator rating', 'Engine rating',
        'Wing area', 'Stall speed', 'Rotate speed', 'Engine out climb angle',
        'HX nozzle area', 'Coolant duct cruise drag', 'Coolant mass',
        'Coolant duct mass flow'
    ]
    print(
        "======================================================================="
    )
    for i, thing in enumerate(vars_list):
        print(nice_print_names[i] + ': ' +
              str(prob.get_val(thing, units=units[i])[0]) + ' ' +
              str(units[i]))

    print('Motor temps (climb): ' +
          str(prob.get_val('climb.propmodel.motorheatsink.T', units='degC')))
    print('Battery temps (climb): ' +
          str(prob.get_val('climb.propmodel.batteryheatsink.T', units='degC')))

    # plot some stuff
    plots = True
    if plots:
        x_var = 'range'
        x_unit = 'NM'
        y_vars = [
            'fltcond|h', 'fltcond|Ueas', 'fuel_used', 'throttle', 'fltcond|vs',
            'propmodel.batt1.SOC', 'propmodel.motorheatsink.T',
Example #32
0
def brachistochrone_min_time(transcription='gauss-lobatto',
                             num_segments=8,
                             transcription_order=3,
                             compressed=True,
                             sim_record='brach_min_time_sim.db',
                             optimizer='SLSQP',
                             dynamic_simul_derivs=True,
                             force_alloc_complex=False,
                             solve_segments=False,
                             run_driver=True):
    p = Problem(model=Group())

    if optimizer == 'SNOPT':
        p.driver = pyOptSparseDriver()
        p.driver.options['optimizer'] = optimizer
        p.driver.opt_settings['Major iterations limit'] = 100
        p.driver.opt_settings['Major feasibility tolerance'] = 1.0E-6
        p.driver.opt_settings['Major optimality tolerance'] = 1.0E-6
        p.driver.opt_settings['iSumm'] = 6
    else:
        p.driver = ScipyOptimizeDriver()

    p.driver.options['dynamic_simul_derivs'] = dynamic_simul_derivs

    if transcription == 'runge-kutta':
        transcription = RungeKutta(num_segments=num_segments,
                                   compressed=compressed)
    elif transcription == 'gauss-lobatto':
        transcription = GaussLobatto(num_segments=num_segments,
                                     order=transcription_order,
                                     compressed=compressed)
    elif transcription == 'radau-ps':
        transcription = Radau(num_segments=num_segments,
                              order=transcription_order,
                              compressed=compressed)

    phase = Phase(ode_class=BrachistochroneVectorStatesODE,
                  transcription=transcription)

    p.model.add_subsystem('phase0', phase)

    phase.set_time_options(fix_initial=True, duration_bounds=(.5, 10))

    fix_final = not solve_segments  # can't fix final position if you're solving the segments
    phase.set_state_options('pos',
                            fix_initial=True,
                            fix_final=fix_final,
                            solve_segments=solve_segments)
    phase.set_state_options('v',
                            fix_initial=True,
                            fix_final=False,
                            solve_segments=solve_segments)

    phase.add_control('theta',
                      continuity=True,
                      rate_continuity=True,
                      units='deg',
                      lower=0.01,
                      upper=179.9)

    phase.add_design_parameter('g', units='m/s**2', opt=False, val=9.80665)

    # Minimize time at the end of the phase
    phase.add_objective('time', loc='final', scaler=10)

    p.model.linear_solver = DirectSolver()
    p.setup(check=True, force_alloc_complex=force_alloc_complex)

    p['phase0.t_initial'] = 0.0
    p['phase0.t_duration'] = 2.0

    pos0 = [0, 10]
    posf = [10, 5]

    p['phase0.states:pos'] = phase.interpolate(ys=[pos0, posf],
                                               nodes='state_input')
    p['phase0.states:v'] = phase.interpolate(ys=[0, 9.9], nodes='state_input')
    p['phase0.controls:theta'] = phase.interpolate(ys=[5, 100],
                                                   nodes='control_input')
    p['phase0.design_parameters:g'] = 9.80665

    p.run_model()
    if run_driver:
        p.run_driver()

    # Plot results
    if SHOW_PLOTS:
        p.run_driver()
        exp_out = phase.simulate(record_file=sim_record)

        fig, ax = plt.subplots()
        fig.suptitle('Brachistochrone Solution')

        x_imp = p.get_val('phase0.timeseries.states:pos')[:, 0]
        y_imp = p.get_val('phase0.timeseries.states:pos')[:, 1]

        x_exp = exp_out.get_val('phase0.timeseries.states:pos')[:, 0]
        y_exp = exp_out.get_val('phase0.timeseries.states:pos')[:, 1]

        ax.plot(x_imp, y_imp, 'ro', label='implicit')
        ax.plot(x_exp, y_exp, 'b-', label='explicit')

        ax.set_xlabel('x (m)')
        ax.set_ylabel('y (m)')
        ax.grid(True)
        ax.legend(loc='upper right')

        fig, ax = plt.subplots()
        fig.suptitle('Brachistochrone Solution')

        x_imp = p.get_val('phase0.timeseries.time')
        y_imp = p.get_val('phase0.timeseries.control_rates:theta_rate2')

        x_exp = exp_out.get_val('phase0.timeseries.time')
        y_exp = exp_out.get_val('phase0.timeseries.control_rates:theta_rate2')

        ax.plot(x_imp, y_imp, 'ro', label='implicit')
        ax.plot(x_exp, y_exp, 'b-', label='explicit')

        ax.set_xlabel('time (s)')
        ax.set_ylabel('theta rate2 (rad/s**2)')
        ax.grid(True)
        ax.legend(loc='lower right')

        plt.show()

    return p
Example #33
0
    def test_control_rate2_boundary_constraint_gl(self):
        p = Problem(model=Group())

        p.driver = ScipyOptimizeDriver()

        p.driver.options['dynamic_simul_derivs'] = True

        phase = Phase(ode_class=BrachistochroneODE,
                      transcription=GaussLobatto(num_segments=20,
                                                 order=3,
                                                 compressed=True))

        p.model.add_subsystem('phase0', phase)

        phase.set_time_options(fix_initial=True, duration_bounds=(0.1, 10))

        phase.set_state_options('x', fix_initial=True, fix_final=True)
        phase.set_state_options('y', fix_initial=True, fix_final=True)
        phase.set_state_options('v', fix_initial=True, fix_final=False)

        phase.add_control('theta',
                          continuity=True,
                          rate_continuity=True,
                          rate2_continuity=True,
                          units='deg',
                          lower=0.01,
                          upper=179.9)

        phase.add_design_parameter('g', units='m/s**2', opt=False, val=9.80665)

        phase.add_boundary_constraint('theta_rate2',
                                      loc='final',
                                      equals=0.0,
                                      units='deg/s**2')

        # Minimize time at the end of the phase
        phase.add_objective('time')

        p.model.linear_solver = DirectSolver()
        p.setup(check=True)

        p['phase0.t_initial'] = 0.0
        p['phase0.t_duration'] = 2.0

        p['phase0.states:x'] = phase.interpolate(ys=[0, 10],
                                                 nodes='state_input')
        p['phase0.states:y'] = phase.interpolate(ys=[10, 5],
                                                 nodes='state_input')
        p['phase0.states:v'] = phase.interpolate(ys=[0, 9.9],
                                                 nodes='state_input')
        p['phase0.controls:theta'] = phase.interpolate(ys=[5, 100],
                                                       nodes='control_input')
        p['phase0.design_parameters:g'] = 8

        p.run_driver()

        plt.plot(p.get_val('phase0.timeseries.states:x'),
                 p.get_val('phase0.timeseries.states:y'), 'ko')

        plt.figure()

        plt.plot(p.get_val('phase0.timeseries.time'),
                 p.get_val('phase0.timeseries.controls:theta'), 'ro')

        plt.plot(p.get_val('phase0.timeseries.time'),
                 p.get_val('phase0.timeseries.control_rates:theta_rate'), 'bo')

        plt.plot(p.get_val('phase0.timeseries.time'),
                 p.get_val('phase0.timeseries.control_rates:theta_rate2'),
                 'go')
        plt.show()

        assert_rel_error(
            self,
            p.get_val('phase0.timeseries.control_rates:theta_rate2')[-1],
            0,
            tolerance=1.0E-6)
    def test_doc_ssto_linear_tangent_guidance(self):
        import numpy as np
        import matplotlib.pyplot as plt
        from openmdao.api import Problem, Group, ExplicitComponent, DirectSolver, \
            pyOptSparseDriver
        from openmdao.utils.assert_utils import assert_rel_error
        import dymos as dm
        from dymos.examples.plotting import plot_results

        g = 1.61544  # lunar gravity, m/s**2

        class LaunchVehicle2DEOM(ExplicitComponent):
            """
            Simple 2D Cartesian Equations of Motion for a launch vehicle subject to thrust and drag.
            """
            def initialize(self):
                self.options.declare('num_nodes', types=int)

            def setup(self):
                nn = self.options['num_nodes']

                # Inputs
                self.add_input('vx',
                               val=np.zeros(nn),
                               desc='x velocity',
                               units='m/s')

                self.add_input('vy',
                               val=np.zeros(nn),
                               desc='y velocity',
                               units='m/s')

                self.add_input('m', val=np.zeros(nn), desc='mass', units='kg')

                self.add_input('theta',
                               val=np.zeros(nn),
                               desc='pitch angle',
                               units='rad')

                self.add_input('thrust',
                               val=2100000 * np.ones(nn),
                               desc='thrust',
                               units='N')

                self.add_input('Isp',
                               val=265.2 * np.ones(nn),
                               desc='specific impulse',
                               units='s')

                # Outputs
                self.add_output('xdot',
                                val=np.zeros(nn),
                                desc='velocity component in x',
                                units='m/s')

                self.add_output('ydot',
                                val=np.zeros(nn),
                                desc='velocity component in y',
                                units='m/s')

                self.add_output('vxdot',
                                val=np.zeros(nn),
                                desc='x acceleration magnitude',
                                units='m/s**2')

                self.add_output('vydot',
                                val=np.zeros(nn),
                                desc='y acceleration magnitude',
                                units='m/s**2')

                self.add_output('mdot',
                                val=np.zeros(nn),
                                desc='mass rate of change',
                                units='kg/s')

                # Setup partials
                ar = np.arange(self.options['num_nodes'])

                self.declare_partials(of='xdot',
                                      wrt='vx',
                                      rows=ar,
                                      cols=ar,
                                      val=1.0)
                self.declare_partials(of='ydot',
                                      wrt='vy',
                                      rows=ar,
                                      cols=ar,
                                      val=1.0)

                self.declare_partials(of='vxdot', wrt='vx', rows=ar, cols=ar)
                self.declare_partials(of='vxdot', wrt='m', rows=ar, cols=ar)
                self.declare_partials(of='vxdot',
                                      wrt='theta',
                                      rows=ar,
                                      cols=ar)
                self.declare_partials(of='vxdot',
                                      wrt='thrust',
                                      rows=ar,
                                      cols=ar)

                self.declare_partials(of='vydot', wrt='m', rows=ar, cols=ar)
                self.declare_partials(of='vydot',
                                      wrt='theta',
                                      rows=ar,
                                      cols=ar)
                self.declare_partials(of='vydot', wrt='vy', rows=ar, cols=ar)
                self.declare_partials(of='vydot',
                                      wrt='thrust',
                                      rows=ar,
                                      cols=ar)

                self.declare_partials(of='mdot',
                                      wrt='thrust',
                                      rows=ar,
                                      cols=ar)
                self.declare_partials(of='mdot', wrt='Isp', rows=ar, cols=ar)

            def compute(self, inputs, outputs):
                theta = inputs['theta']
                cos_theta = np.cos(theta)
                sin_theta = np.sin(theta)
                vx = inputs['vx']
                vy = inputs['vy']
                m = inputs['m']
                F_T = inputs['thrust']
                Isp = inputs['Isp']

                outputs['xdot'] = vx
                outputs['ydot'] = vy
                outputs['vxdot'] = F_T * cos_theta / m
                outputs['vydot'] = F_T * sin_theta / m - g
                outputs['mdot'] = -F_T / (g * Isp)

            def compute_partials(self, inputs, jacobian):
                theta = inputs['theta']
                cos_theta = np.cos(theta)
                sin_theta = np.sin(theta)
                m = inputs['m']
                F_T = inputs['thrust']
                Isp = inputs['Isp']

                # jacobian['vxdot', 'vx'] = -CDA * rho * vx / m
                jacobian['vxdot', 'm'] = -(F_T * cos_theta) / m**2
                jacobian['vxdot', 'theta'] = -(F_T / m) * sin_theta
                jacobian['vxdot', 'thrust'] = cos_theta / m

                # jacobian['vydot', 'vy'] = -CDA * rho * vy / m
                jacobian['vydot', 'm'] = -(F_T * sin_theta) / m**2
                jacobian['vydot', 'theta'] = (F_T / m) * cos_theta
                jacobian['vydot', 'thrust'] = sin_theta / m

                jacobian['mdot', 'thrust'] = -1.0 / (g * Isp)
                jacobian['mdot', 'Isp'] = F_T / (g * Isp**2)

        class LinearTangentGuidanceComp(ExplicitComponent):
            """ Compute pitch angle from static controls governing linear expression for
                pitch angle tangent as function of time.
            """
            def initialize(self):
                self.options.declare('num_nodes', types=int)

            def setup(self):
                nn = self.options['num_nodes']

                self.add_input('a_ctrl',
                               val=np.zeros(nn),
                               desc='linear tangent slope',
                               units='1/s')

                self.add_input('b_ctrl',
                               val=np.zeros(nn),
                               desc='tangent of theta at t=0',
                               units=None)

                self.add_input('time_phase',
                               val=np.zeros(nn),
                               desc='time',
                               units='s')

                self.add_output('theta',
                                val=np.zeros(nn),
                                desc='pitch angle',
                                units='rad')

                # Setup partials
                arange = np.arange(self.options['num_nodes'])

                self.declare_partials(of='theta',
                                      wrt='a_ctrl',
                                      rows=arange,
                                      cols=arange,
                                      val=1.0)
                self.declare_partials(of='theta',
                                      wrt='b_ctrl',
                                      rows=arange,
                                      cols=arange,
                                      val=1.0)
                self.declare_partials(of='theta',
                                      wrt='time_phase',
                                      rows=arange,
                                      cols=arange,
                                      val=1.0)

            def compute(self, inputs, outputs):
                a = inputs['a_ctrl']
                b = inputs['b_ctrl']
                t = inputs['time_phase']
                outputs['theta'] = np.arctan(a * t + b)

            def compute_partials(self, inputs, jacobian):
                a = inputs['a_ctrl']
                b = inputs['b_ctrl']
                t = inputs['time_phase']

                x = a * t + b
                denom = x**2 + 1.0

                jacobian['theta', 'a_ctrl'] = t / denom
                jacobian['theta', 'b_ctrl'] = 1.0 / denom
                jacobian['theta', 'time_phase'] = a / denom

        @dm.declare_time(units='s', targets=['guidance.time_phase'])
        @dm.declare_state('x', rate_source='eom.xdot', units='m')
        @dm.declare_state('y', rate_source='eom.ydot', units='m')
        @dm.declare_state('vx',
                          rate_source='eom.vxdot',
                          targets=['eom.vx'],
                          units='m/s')
        @dm.declare_state('vy',
                          rate_source='eom.vydot',
                          targets=['eom.vy'],
                          units='m/s')
        @dm.declare_state('m',
                          rate_source='eom.mdot',
                          targets=['eom.m'],
                          units='kg')
        @dm.declare_parameter('thrust', targets=['eom.thrust'], units='N')
        @dm.declare_parameter('a_ctrl',
                              targets=['guidance.a_ctrl'],
                              units='1/s')
        @dm.declare_parameter('b_ctrl',
                              targets=['guidance.b_ctrl'],
                              units=None)
        @dm.declare_parameter('Isp', targets=['eom.Isp'], units='s')
        class LaunchVehicleLinearTangentODE(Group):
            """
            The LaunchVehicleLinearTangentODE for this case consists of a guidance component and
            the EOM.  Guidance is simply an OpenMDAO ExecComp which computes the arctangent of the
            tan_theta variable.
            """
            def initialize(self):
                self.options.declare(
                    'num_nodes',
                    types=int,
                    desc='Number of nodes to be evaluated in the RHS')

            def setup(self):
                nn = self.options['num_nodes']
                self.add_subsystem('guidance',
                                   LinearTangentGuidanceComp(num_nodes=nn))
                self.add_subsystem('eom', LaunchVehicle2DEOM(num_nodes=nn))
                self.connect('guidance.theta', 'eom.theta')

        #
        # Setup and solve the optimal control problem
        #
        p = Problem(model=Group())

        p.driver = pyOptSparseDriver()
        p.driver.options['dynamic_simul_derivs'] = True

        traj = dm.Trajectory()
        p.model.add_subsystem('traj', traj)

        phase = dm.Phase(ode_class=LaunchVehicleLinearTangentODE,
                         transcription=dm.GaussLobatto(num_segments=10,
                                                       order=5,
                                                       compressed=True))

        traj.add_phase('phase0', phase)

        phase.set_time_options(initial_bounds=(0, 0),
                               duration_bounds=(10, 1000))

        phase.set_state_options('x', fix_initial=True, lower=0)
        phase.set_state_options('y', fix_initial=True, lower=0)
        phase.set_state_options('vx', fix_initial=True, lower=0)
        phase.set_state_options('vy', fix_initial=True)
        phase.set_state_options('m', fix_initial=True)

        phase.add_boundary_constraint('y',
                                      loc='final',
                                      equals=1.85E5,
                                      linear=True)
        phase.add_boundary_constraint('vx', loc='final', equals=1627.0)
        phase.add_boundary_constraint('vy', loc='final', equals=0)

        phase.add_design_parameter('a_ctrl', units='1/s', opt=True)
        phase.add_design_parameter('b_ctrl', units=None, opt=True)
        phase.add_design_parameter('thrust',
                                   units='N',
                                   opt=False,
                                   val=3.0 * 50000.0 * 1.61544)
        phase.add_design_parameter('Isp', units='s', opt=False, val=1.0E6)

        phase.add_objective('time', index=-1, scaler=0.01)

        p.model.linear_solver = DirectSolver()

        phase.add_timeseries_output('guidance.theta', units='deg')

        p.setup(check=True)

        p['traj.phase0.t_initial'] = 0.0
        p['traj.phase0.t_duration'] = 500.0
        p['traj.phase0.states:x'] = phase.interpolate(ys=[0, 350000.0],
                                                      nodes='state_input')
        p['traj.phase0.states:y'] = phase.interpolate(ys=[0, 185000.0],
                                                      nodes='state_input')
        p['traj.phase0.states:vx'] = phase.interpolate(ys=[0, 1627.0],
                                                       nodes='state_input')
        p['traj.phase0.states:vy'] = phase.interpolate(ys=[1.0E-6, 0],
                                                       nodes='state_input')
        p['traj.phase0.states:m'] = phase.interpolate(ys=[50000, 50000],
                                                      nodes='state_input')
        p['traj.phase0.design_parameters:a_ctrl'] = -0.01
        p['traj.phase0.design_parameters:b_ctrl'] = 3.0

        p.run_driver()

        #
        # Check the results.
        #
        assert_rel_error(self,
                         p.get_val('traj.phase0.timeseries.time')[-1],
                         481,
                         tolerance=0.01)

        #
        # Get the explitly simulated results
        #
        exp_out = traj.simulate()

        #
        # Plot the results
        #
        plot_results(
            [('traj.phase0.timeseries.states:x',
              'traj.phase0.timeseries.states:y', 'range (m)', 'altitude (m)'),
             ('traj.phase0.timeseries.time', 'traj.phase0.timeseries.theta',
              'range (m)', 'altitude (m)')],
            title=
            'Single Stage to Orbit Solution Using Linear Tangent Guidance',
            p_sol=p,
            p_sim=exp_out)

        plt.show()
Example #35
0
    def test_design_parameter_boundary_constraint(self):
        p = Problem(model=Group())

        p.driver = ScipyOptimizeDriver()
        p.driver.options['dynamic_simul_derivs'] = True

        phase = Phase(ode_class=BrachistochroneODE,
                      transcription=GaussLobatto(num_segments=20,
                                                 order=3,
                                                 compressed=True))

        p.model.add_subsystem('phase0', phase)

        phase.set_time_options(fix_initial=True, duration_bounds=(.5, 10))

        phase.set_state_options('x', fix_initial=True, fix_final=True)
        phase.set_state_options('y', fix_initial=True, fix_final=True)
        phase.set_state_options('v', fix_initial=True, fix_final=False)

        phase.add_control('theta',
                          continuity=True,
                          rate_continuity=True,
                          units='deg',
                          lower=0.01,
                          upper=179.9)

        phase.add_design_parameter('g', units='m/s**2', opt=True, val=9.80665)

        # We'll let g vary, but make sure it hits the desired value.
        # It's a static design parameter, so it shouldn't matter whether we enforce it
        # at the start or the end of the phase, so here we'll do both.
        # Note if we make these equality constraints, some optimizers (SLSQP) will
        # see the problem as infeasible.
        phase.add_boundary_constraint('g',
                                      loc='initial',
                                      units='m/s**2',
                                      upper=9.80665)
        phase.add_boundary_constraint('g',
                                      loc='final',
                                      units='m/s**2',
                                      upper=9.80665)

        # Minimize time at the end of the phase
        phase.add_objective('time_phase', loc='final', scaler=10)

        p.model.linear_solver = DirectSolver()
        p.setup(check=True)

        p['phase0.t_initial'] = 0.0
        p['phase0.t_duration'] = 2.0

        p['phase0.states:x'] = phase.interpolate(ys=[0, 10],
                                                 nodes='state_input')
        p['phase0.states:y'] = phase.interpolate(ys=[10, 5],
                                                 nodes='state_input')
        p['phase0.states:v'] = phase.interpolate(ys=[0, 9.9],
                                                 nodes='state_input')
        p['phase0.controls:theta'] = phase.interpolate(ys=[5, 100],
                                                       nodes='control_input')
        p['phase0.design_parameters:g'] = 5

        p.run_driver()

        assert_rel_error(self,
                         p.get_val('phase0.timeseries.time')[-1],
                         1.8016,
                         tolerance=1.0E-4)
        assert_rel_error(self,
                         p.get_val('phase0.timeseries.design_parameters:g')[0],
                         9.80665,
                         tolerance=1.0E-6)
        assert_rel_error(
            self,
            p.get_val('phase0.timeseries.design_parameters:g')[-1],
            9.80665,
            tolerance=1.0E-6)
Example #36
0
        print("Average Final T_1[K] = ", T_1)
        print("Max Overall T_2[K] = ", T2_max)
        print("Max Final T_2[K] = ", T_2)
        # print("Max Overall Td [K] = ", Td_max)
        # print("Temp Ratio = ", T2_max/Td_max)
        print("Maximum Final T[K] = ", u.vector().max())
        print("Minimum Final T[K] = ", u.vector().min())

        #o['temp1'] = u.vector().max()
        o['temp2_data'] = T_2  #T2_max
        o['temp3_data'] = T_1  #Td_max


if __name__ == '__main__':
    from openmdao.api import Problem

    nn = 1
    prob = Problem()

    prob.model.add_subsystem('baseline_temp',
                             FenicsBaseline(num_nodes=nn, cluster=True),
                             promotes=['*'])

    prob.setup(force_alloc_complex=True)
    prob.run_model()

    #print(prob.get_val('temp1'))
    print(prob.get_val('temp2_data'))
    print(prob.get_val('temp3_data'))
Example #37
0
        outputs['A'] = batt_l * batt_h
        outputs['ins_side_sep_area'] = outputs['A'] * num_stacks * (num_cells +
                                                                    1)
        outputs['ins_end_sep_area'] = batt_h * (
            (num_cells * L_flux) + (batt_side_sep *
                                    (num_cells + 1))) * (num_stacks + 1)
        outputs['ins_volume'] = (outputs['ins_backing_area'] +
                                 outputs['ins_side_sep_area'] +
                                 outputs['ins_end_sep_area']) * ins_thickness
        outputs['ins_mass'] = outputs['ins_volume'] * ins_density


if __name__ == "__main__":
    from openmdao.api import Problem

    nn = 1
    prob = Problem()

    prob.model.add_subsystem('ins_mass',
                             insulationMass(num_nodes=nn),
                             promotes=['*'])

    prob.setup(force_alloc_complex=True)
    prob.run_model()

    print('ins_backing_area = ', prob.get_val('ins_mass.ins_backing_area'))
    print('ins_side_sep_area = ', prob.get_val('ins_mass.ins_side_sep_area'))
    print('ins_end_sep_area = ', prob.get_val('ins_mass.ins_end_sep_area'))
    print('ins_volume = ', prob.get_val('ins_mass.ins_volume'))
    print('ins_mass = ', prob.get_val('ins_mass.ins_mass'))
Example #38
0

# # ------------ Derivative Checks --------------- #
if __name__ == "__main__":
    from openmdao.api import Problem

    nn = 1
    geom = 'FLAT'
    prob = Problem()

    prob.model.add_subsystem('comp1',
                             SizeComp(num_nodes=nn, geom=geom),
                             promotes=['*'])
    # prob.model.add_subsystem('comp2', CoreGeometries(num_nodes=nn, geom=geom), promotes=['*'])

    prob.setup(force_alloc_complex=True)
    prob.run_model()
    # prob.check_partials(method='cs', compact_print=True)

    print('A_flux = ', prob.get_val('comp1.A_flux'))
    print('L_eff = ', prob.get_val('comp1.L_eff'))

    # print('A_w = ', prob.get_val('comp2.A_w'))
    # print('A_wk = ', prob.get_val('comp2.A_wk'))
    # print('A_inter = ', prob.get_val('comp2.A_inter'))

    # print('r_i', prob.get_val('comp1.r_i'))
    # print('A_flux', prob.get_val('comp1.A_flux'))
    # print('A_evap', prob.get_val('comp1.A_evap'))
    # print('L_eff', prob.get_val('comp1.L_eff'))
Example #39
0
    def test_brachistochrone_undecorated_ode_gl(self):
        import numpy as np
        import matplotlib
        matplotlib.use('Agg')
        import matplotlib.pyplot as plt
        from openmdao.api import Problem, Group, ScipyOptimizeDriver, DirectSolver
        from openmdao.utils.assert_utils import assert_rel_error
        from dymos import Phase, GaussLobatto

        p = Problem(model=Group())
        p.driver = ScipyOptimizeDriver()

        phase = Phase(ode_class=BrachistochroneODE,
                      transcription=GaussLobatto(num_segments=10))

        p.model.add_subsystem('phase0', phase)

        phase.set_time_options(initial_bounds=(0, 0),
                               duration_bounds=(.5, 10),
                               units='s')

        phase.set_state_options('x',
                                fix_initial=True,
                                fix_final=True,
                                rate_source='xdot',
                                units='m')
        phase.set_state_options('y',
                                fix_initial=True,
                                fix_final=True,
                                rate_source='ydot',
                                units='m')
        phase.set_state_options('v',
                                fix_initial=True,
                                rate_source='vdot',
                                targets=['v'],
                                units='m/s')

        phase.add_control('theta',
                          units='deg',
                          rate_continuity=False,
                          lower=0.01,
                          upper=179.9,
                          targets=['theta'])

        phase.add_design_parameter('g',
                                   units='m/s**2',
                                   opt=False,
                                   val=9.80665,
                                   targets=['g'])

        # Minimize time at the end of the phase
        phase.add_objective('time', loc='final', scaler=10)

        p.model.linear_solver = DirectSolver()

        p.setup()

        p['phase0.t_initial'] = 0.0
        p['phase0.t_duration'] = 2.0

        p['phase0.states:x'] = phase.interpolate(ys=[0, 10],
                                                 nodes='state_input')
        p['phase0.states:y'] = phase.interpolate(ys=[10, 5],
                                                 nodes='state_input')
        p['phase0.states:v'] = phase.interpolate(ys=[0, 9.9],
                                                 nodes='state_input')
        p['phase0.controls:theta'] = phase.interpolate(ys=[5, 100.5],
                                                       nodes='control_input')

        # Solve for the optimal trajectory
        p.run_driver()

        # Test the results
        assert_rel_error(self,
                         p.get_val('phase0.timeseries.time')[-1],
                         1.8016,
                         tolerance=1.0E-3)