• Stars
    star
    206
  • Rank 190,504 (Top 4 %)
  • Language
    Python
  • License
    Apache License 2.0
  • Created almost 7 years ago
  • Updated about 1 month ago

Reviews

There are no reviews yet. Be the first to send feedback to the community and the maintainers!

Repository Details

Open Source Optimization of Dynamic Multidisciplinary Systems

Dymos: Open Source Optimization of Dynamic Multidisciplinary Systems

Dymos Tests Coverage Status

DOI

Dymos is a framework for the simulation and optimization of dynamical systems within the OpenMDAO Multidisciplinary Analysis and Optimization environment. Dymos leverages implicit and explicit simulation techniques to simulate generic dynamic systems of arbitary complexity.

The software has two primary objectives:

  • Provide a generic ODE integration interface that allows for the analysis of dynamical systems.
  • Allow the user to solve optimal control problems involving dynamical multidisciplinary systems.

Installation

The default installation of the developmental version of Dymos will install the minimum number of prerequisites:

python -m pip install dymos

More advanced installation instructions are available here.

Citation

See our overview paper in the Journal of Open Source Software

If you use Dymos in your work, please cite:

@article{Falck2021,
  doi = {10.21105/joss.02809},
  url = {https://doi.org/10.21105/joss.02809},
  year = {2021},
  publisher = {The Open Journal},
  volume = {6},
  number = {59},
  pages = {2809},
  author = {Robert Falck and Justin S. Gray and Kaushik Ponnapalli and Ted Wright},
  title = {dymos: A Python package for optimal control of multidisciplinary systems},
  journal = {Journal of Open Source Software}
}

Documentation

Online documentation is available at https://openmdao.github.io/dymos/

Defining Ordinary Differential Equations

The first step in simulating or optimizing a dynamical system is to define the ordinary differential equations to be integrated. The user first builds an OpenMDAO model which has outputs that provide the rates of the state variables. This model can be an OpenMDAO model of arbitrary complexity, including nested groups and components, layers of nonlinear solvers, etc.

Dymos solutions are constructed of one or more Phases. When setting up a phase, we add state variables, dynamic controls, and parameters, tell Dymos how the value of each should be connected to the ODE system, and tell Dymos the variable paths in the system that contain the rates of our state variables that are to be integrated.

Integrating Ordinary Differential Equations

Dymos's solver-based pseudspectral transcriptions provide the ability to numerically integrate the ODE system it is given. Used in an optimal control context, these provide a shooting method in which each iteration provides a physically viable trajectory.

Pseudospectral Methods

Dymos currently supports the Radau Pseudospectral Method and high-order Gauss-Lobatto transcriptions. These implicit techniques rely on the optimizer to impose "defect" constraints which enforce the physical accuracy of the resulting trajectories. To verify the physical accuracy of the solutions, Dymos can explicitly integrate them using variable-step methods.

Solving Optimal Control Problems

Dymos uses the concept of Phases to support optimal control of dynamical systems. Users connect one or more Phases to construct trajectories. Each Phase can have its own:

  • Optimal Control Transcription (Gauss-Lobatto or Radau Pseudospectral)
  • Equations of motion
  • Boundary and path constraints

Dymos Phases and Trajectories are ultimately just OpenMDAO Groups that can exist in a problem along with numerous other models, allowing for the simultaneous optimization of systems and dynamics.

import numpy as np
import openmdao.api as om
import dymos as dm
import matplotlib.pyplot as plt

# First define a system which computes the equations of motion
class BrachistochroneEOM(om.ExplicitComponent):
    def initialize(self):
        self.options.declare('num_nodes', types=int)

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

        # Inputs
        self.add_input('v', val=np.zeros(nn), units='m/s', desc='velocity')
        self.add_input('theta', val=np.zeros(nn), units='rad', desc='angle of wire')
        self.add_output('xdot', val=np.zeros(nn), units='m/s', desc='x rate of change')
        self.add_output('ydot', val=np.zeros(nn), units='m/s', desc='y rate of change')
        self.add_output('vdot', val=np.zeros(nn), units='m/s**2', desc='v rate of change')

        # Ask OpenMDAO to compute the partial derivatives using complex-step
        # with a partial coloring algorithm for improved performance
        self.declare_partials(of='*', wrt='*', method='cs')
        self.declare_coloring(wrt='*', method='cs', show_summary=True)

    def compute(self, inputs, outputs):
        v, theta = inputs.values()
        outputs['vdot'] = 9.80665 * np.cos(theta)
        outputs['xdot'] = v * np.sin(theta)
        outputs['ydot'] = -v * np.cos(theta)

p = om.Problem()

# Define a Trajectory object
traj = p.model.add_subsystem('traj', dm.Trajectory())

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

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

# Set the time options
phase.set_time_options(fix_initial=True,
                       duration_bounds=(0.5, 10.0))
# Set the state options
phase.add_state('x', rate_source='xdot',
                fix_initial=True, fix_final=True)
phase.add_state('y', rate_source='ydot',
                fix_initial=True, fix_final=True)
phase.add_state('v', rate_source='vdot',
                fix_initial=True, fix_final=False)
# Define theta as a control.
phase.add_control(name='theta', units='rad',
                  lower=0, upper=np.pi)
# Minimize final time.
phase.add_objective('time', loc='final')

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

# Allow OpenMDAO to automatically determine total
# derivative sparsity pattern.
# This works in conjunction with partial derivative
# coloring to give a large speedup
p.driver.declare_coloring()

# Setup the problem
p.setup()

# Now that the OpenMDAO problem is setup, we can guess the
# values of time, states, and controls.
p.set_val('traj.phase0.t_duration', 2.0)

# States and controls here use a linearly interpolated
# initial guess along the trajectory.
p.set_val('traj.phase0.states:x',
          phase.interp('x', ys=[0, 10]),
          units='m')
p.set_val('traj.phase0.states:y',
          phase.interp('y', ys=[10, 5]),
          units='m')
p.set_val('traj.phase0.states:v',
          phase.interp('v', ys=[0, 5]),
          units='m/s')
# constant initial guess for control
p.set_val('traj.phase0.controls:theta', 90, units='deg')

# Run the driver to solve the problem and generate default plots of
# state and control values vs time
dm.run_problem(p, make_plots=True, simulate=True)

# Load the solution and simulation files.
sol_case = om.CaseReader('dymos_solution.db').get_case('final')
sim_case = om.CaseReader('dymos_simulation.db').get_case('final')

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

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

axes[0].plot(sim_case.get_val('traj.phase0.timeseries.states:x'),
             sim_case.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(sol_case.get_val('traj.phase0.timeseries.time'),
             sol_case.get_val('traj.phase0.timeseries.controls:theta',
                              units='deg'),
             'ro', label='solution')

axes[1].plot(sim_case.get_val('traj.phase0.timeseries.time'),
             sim_case.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()

Brachistochrone Solution

More Repositories

1

OpenMDAO

OpenMDAO repository.
Python
542
star
2

OpenMDAO-Framework

A python based open-source (Apache 2.0) engineering analysis framework designed to facilitate the use of MDAO. To add issues, visit our user forums at http://www.openmdao.org/forum . NOTE: this version is no longer being developed. The current active version can be found here: https://github.com/OpenMDAO/OpenMDAO.
Python
152
star
3

Aviary

NASA's aircraft analysis, design, and optimization tool
Python
132
star
4

OpenMDAO1

OpenMDAO is a high-performance computing platform for systems analysis and optimization that enables you to decompose your models, making them easier to build and maintain, while still solving them in a tightly-coupled manner with efficient parallel numerical methods.
Python
121
star
5

pyCycle

Thermodynamic cycle modeling library, built on top of OpenMDAO
Python
76
star
6

mphys

Multiphysics with OpenMDAO
Python
47
star
7

EngSketchPad

C
22
star
8

EGADS

C
18
star
9

AcousticAnalogies.jl

Julia
15
star
10

RevHack2020

OpenMDAO 2020 Reverse Hackathon
Python
14
star
11

POEMs

Proposals for OpenMDAO Enhancements
HTML
14
star
12

openmdao_training

Python
11
star
13

lectures

Lectures on various topics having to do with Optimization in general and OpenMDAO in particular
Python
9
star
14

build_pyoptsparse

python script to build/install pyoptsparse with IPOPT (and optionally SNOPT)
Python
9
star
15

zappy

load flow analysis for AC and DC electric systems with analytic derivatives, implemented in OpenMDAO
Python
6
star
16

CADRE

Python
6
star
17

OpenMDAO-Procedures

Procedures for OpenMDAO maintainers
Makefile
6
star
18

SimplePylab

Simple script to create virtual environment with numpy, scipy, matplotlib and ipython.
Python
6
star
19

openmdao_testapp

Web app to manage openmdao automated testing
Python
4
star
20

pyV3D

python web-based geometry viewer
C
3
star
21

marathon-aircraft

Aero-Velo Marathon Aircraft
Python
3
star
22

OpenMDAO_Book

Jupyter Notebook
3
star
23

Aviary_Community

Supplemental repo containing aviary models submitted by the community.
Python
3
star
24

KinematicCoordinateTransformations.jl

Perform coordinate system transformations of position, velocity, acceleration, and jerk.
Julia
2
star
25

pygem

python wrappers for the GEM libraries diamond and quartz
C
2
star
26

AcousticMetrics.jl

Calculate common acoustic metrics with Julia.
Julia
1
star
27

dymos_training

Training resources for Dymos
Python
1
star
28

flops_wrapper

OpenMDAO component wrapper for FLOPS
Python
1
star
29

GEM

C
1
star
30

NAS_Access

An ExternalComponent that wraps and runs code on NASA's NAS Pleiades supercomputer. You must have an account on Pleiades to make use of this.
1
star
31

library_template

A structure that can be a starting point for developers who want to create projects that depend on OpenMDAO.
Python
1
star