Skip to content

Commit

Permalink
Merge branch 'master' of github.com:OpenMDAO/dymos into cartpole_docs
Browse files Browse the repository at this point in the history
  • Loading branch information
bernardopacini committed Aug 19, 2022
2 parents 98842ee + 425becc commit fbbfe54
Show file tree
Hide file tree
Showing 4 changed files with 165 additions and 47 deletions.
56 changes: 35 additions & 21 deletions .github/workflows/dymos_docs_workflow.yml
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ jobs:
NUMPY: 1
SCIPY: 1
PETSc: 3
PYOPTSPARSE: 'main'
PYOPTSPARSE: 'latest'
SNOPT: 7.7
MBI: 1
OPENMDAO: 'dev'
Expand Down Expand Up @@ -140,30 +140,44 @@ jobs:
echo "============================================================="
echo "Install pyoptsparse"
echo "============================================================="
git clone -q https://github.com/OpenMDAO/build_pyoptsparse
cd build_pyoptsparse
chmod 755 ./build_pyoptsparse.sh
if [[ "${{ matrix.PETSc }}" && "${{ matrix.PYOPTSPARSE }}" == "v1.2" ]]; then
PAROPT=-a
fi
if [[ "${{ matrix.SNOPT }}" == "7.7" && "${{ secrets.SNOPT_LOCATION_77 }}" ]]; then
echo " > Secure copying SNOPT 7.7 over SSH"
mkdir SNOPT
scp -qr ${{ secrets.SNOPT_LOCATION_77 }} SNOPT
./build_pyoptsparse.sh $PAROPT -b "${{ matrix.PYOPTSPARSE }}" -s SNOPT/src
elif [[ "${{ matrix.SNOPT }}" == "7.2" && "${{ secrets.SNOPT_LOCATION_72 }}" ]]; then
echo " > Secure copying SNOPT 7.2 over SSH"
mkdir SNOPT
scp -qr ${{ secrets.SNOPT_LOCATION_72 }} SNOPT
./build_pyoptsparse.sh $PAROPT -b "${{ matrix.PYOPTSPARSE }}" -s SNOPT/source
else
if [[ "${{ matrix.PYOPTSPARSE }}" == "conda-forge" ]]; then
if [[ "${{ matrix.SNOPT }}" ]]; then
echo "SNOPT ${{ matrix.SNOPT }} was requested but is not available on conda-forge"
fi
conda install -c conda-forge pyoptsparse
else
pip install git+https://github.com/OpenMDAO/build_pyoptsparse
if [[ "${{ matrix.PYOPTSPARSE }}" == "latest" ]]; then
LATEST_URL=`curl -fsSLI -o /dev/null -w %{url_effective} https://github.com/mdolab/pyoptsparse/releases/latest`
LATEST_VER=`echo $LATEST_URL | awk '{split($0,a,"/tag/"); print a[2]}'`
BRANCH="-b $LATEST_VER"
else
BRANCH="-b ${{ matrix.PYOPTSPARSE }}"
fi
if [[ "${{ matrix.PAROPT }}" ]]; then
PAROPT="-a"
fi
if [[ "${{ matrix.SNOPT }}" == "7.7" && "${{ secrets.SNOPT_LOCATION_77 }}" ]]; then
echo " > Secure copying SNOPT 7.7 over SSH"
mkdir SNOPT
scp -qr ${{ secrets.SNOPT_LOCATION_77 }} SNOPT
SNOPT="-s SNOPT/src"
elif [[ "${{ matrix.SNOPT }}" == "7.2" && "${{ secrets.SNOPT_LOCATION_72 }}" ]]; then
echo " > Secure copying SNOPT 7.2 over SSH"
mkdir SNOPT
scp -qr ${{ secrets.SNOPT_LOCATION_72 }} SNOPT
SNOPT="-s SNOPT/source"
elif [[ "${{ matrix.SNOPT }}" ]]; then
echo "SNOPT version ${{ matrix.SNOPT }} was requested but source is not available"
fi
./build_pyoptsparse.sh $PAROPT -b "${{ matrix.PYOPTSPARSE }}"
build_pyoptsparse $BRANCH $PAROPT $SNOPT
fi
cd ..
echo "LD_LIBRARY_PATH=$HOME/ipopt/lib" >> $GITHUB_ENV
- name: Install MBI
if: (github.event_name != 'workflow_dispatch' || matrix.NAME == 'latest') && matrix.MBI
Expand Down
56 changes: 35 additions & 21 deletions .github/workflows/dymos_tests_workflow.yml
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,7 @@ jobs:
NUMPY: 1
SCIPY: 1
PETSc: 3
PYOPTSPARSE: 'main'
PYOPTSPARSE: 'latest'
SNOPT: 7.7
MBI: 1
OPENMDAO: 'dev'
Expand Down Expand Up @@ -182,30 +182,44 @@ jobs:
echo "============================================================="
echo "Install pyoptsparse"
echo "============================================================="
git clone -q https://github.com/OpenMDAO/build_pyoptsparse
cd build_pyoptsparse
chmod 755 ./build_pyoptsparse.sh
if [[ "${{ matrix.PETSc }}" && "${{ matrix.PYOPTSPARSE }}" == "v1.2" ]]; then
PAROPT=-a
fi
if [[ "${{ matrix.SNOPT }}" == "7.7" && "${{ secrets.SNOPT_LOCATION_77 }}" ]]; then
echo " > Secure copying SNOPT 7.7 over SSH"
mkdir SNOPT
scp -qr ${{ secrets.SNOPT_LOCATION_77 }} SNOPT
./build_pyoptsparse.sh $PAROPT -b "${{ matrix.PYOPTSPARSE }}" -s SNOPT/src
elif [[ "${{ matrix.SNOPT }}" == "7.2" && "${{ secrets.SNOPT_LOCATION_72 }}" ]]; then
echo " > Secure copying SNOPT 7.2 over SSH"
mkdir SNOPT
scp -qr ${{ secrets.SNOPT_LOCATION_72 }} SNOPT
./build_pyoptsparse.sh $PAROPT -b "${{ matrix.PYOPTSPARSE }}" -s SNOPT/source
else
if [[ "${{ matrix.PYOPTSPARSE }}" == "conda-forge" ]]; then
if [[ "${{ matrix.SNOPT }}" ]]; then
echo "SNOPT ${{ matrix.SNOPT }} was requested but is not available on conda-forge"
fi
conda install -c conda-forge pyoptsparse
else
pip install git+https://github.com/OpenMDAO/build_pyoptsparse
if [[ "${{ matrix.PYOPTSPARSE }}" == "latest" ]]; then
LATEST_URL=`curl -fsSLI -o /dev/null -w %{url_effective} https://github.com/mdolab/pyoptsparse/releases/latest`
LATEST_VER=`echo $LATEST_URL | awk '{split($0,a,"/tag/"); print a[2]}'`
BRANCH="-b $LATEST_VER"
else
BRANCH="-b ${{ matrix.PYOPTSPARSE }}"
fi
if [[ "${{ matrix.PAROPT }}" ]]; then
PAROPT="-a"
fi
if [[ "${{ matrix.SNOPT }}" == "7.7" && "${{ secrets.SNOPT_LOCATION_77 }}" ]]; then
echo " > Secure copying SNOPT 7.7 over SSH"
mkdir SNOPT
scp -qr ${{ secrets.SNOPT_LOCATION_77 }} SNOPT
SNOPT="-s SNOPT/src"
elif [[ "${{ matrix.SNOPT }}" == "7.2" && "${{ secrets.SNOPT_LOCATION_72 }}" ]]; then
echo " > Secure copying SNOPT 7.2 over SSH"
mkdir SNOPT
scp -qr ${{ secrets.SNOPT_LOCATION_72 }} SNOPT
SNOPT="-s SNOPT/source"
elif [[ "${{ matrix.SNOPT }}" ]]; then
echo "SNOPT version ${{ matrix.SNOPT }} was requested but source is not available"
fi
./build_pyoptsparse.sh $PAROPT -b "${{ matrix.PYOPTSPARSE }}"
build_pyoptsparse $BRANCH $PAROPT $SNOPT
fi
cd ..
echo "LD_LIBRARY_PATH=$HOME/ipopt/lib" >> $GITHUB_ENV
- name: Install MBI
if: (github.event_name != 'workflow_dispatch' || matrix.NAME == 'latest') && matrix.MBI
Expand Down
17 changes: 17 additions & 0 deletions dymos/load_case.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
from openmdao.recorders.case import Case
from .phase.phase import Phase
from .trajectory import Trajectory
from openmdao.utils.om_warnings import issue_warning


def find_phases(sys):
Expand Down Expand Up @@ -149,6 +150,12 @@ def load_case(problem, previous_solution):
if init_val_path:
problem.set_val(init_val_path[0], prev_state_val[0, ...], units=prev_state_units)

if options['fix_final']:
warning_message = f"{phase_name}.states:{state_name} specifies 'fix_final=True'. " \
f"If the given restart file has a" \
f" different final value this will overwrite the user-specified value"
issue_warning(warning_message)

# Interpolate the timeseries control outputs from the previous solution onto the new grid.
for control_name, options in phase.control_options.items():
control_path = [s for s in phase_vars if s.endswith(f'{phase_name}.controls:{control_name}')][0]
Expand All @@ -160,6 +167,11 @@ def load_case(problem, previous_solution):
phase.interp(xs=prev_time_val, ys=prev_control_val,
nodes='control_input', kind='slinear'),
units=prev_control_units)
if options['fix_final']:
warning_message = f"{phase_name}.controls:{control_name} specifies 'fix_final=True'. " \
f"If the given restart file has a" \
f" different final value this will overwrite the user-specified value"
issue_warning(warning_message)

# Set the output polynomial control outputs from the previous solution as the value
for pc_name, options in phase.polynomial_control_options.items():
Expand All @@ -169,6 +181,11 @@ def load_case(problem, previous_solution):
prev_pc_val = prev_vars[prev_pc_path]['val']
prev_pc_units = prev_vars[prev_pc_path]['units']
problem.set_val(pc_path, prev_pc_val, units=prev_pc_units)
if options['fix_final']:
warning_message = f"{phase_name}.polynomial_controls:{pc_name} specifies 'fix_final=True'. " \
f"If the given restart file has a" \
f" different final value this will overwrite the user-specified value"
issue_warning(warning_message)

# Set the timeseries parameter outputs from the previous solution as the parameter value
for param_name, options in phase.parameter_options.items():
Expand Down
83 changes: 78 additions & 5 deletions dymos/test/test_load_case.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,8 @@
om_version = tuple([int(s) for s in openmdao.__version__.split('-')[0].split('.')])


def setup_problem(trans=dm.GaussLobatto(num_segments=10), polynomial_control=False):
def setup_problem(trans=dm.GaussLobatto(num_segments=10), polynomial_control=False,
fix_final_state=True, fix_final_control=False):
from dymos.examples.brachistochrone.brachistochrone_ode import BrachistochroneODE

p = om.Problem(model=om.Group())
Expand All @@ -20,15 +21,16 @@ def setup_problem(trans=dm.GaussLobatto(num_segments=10), polynomial_control=Fal

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

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

if not polynomial_control:
phase.add_control('theta', units='deg',
rate_continuity=False, lower=0.01, upper=179.9)
rate_continuity=False, lower=0.01, upper=179.9, fix_final=fix_final_control)
else:
phase.add_polynomial_control('theta', order=1, units='deg', lower=0.01, upper=179.9)
phase.add_polynomial_control('theta', order=1, units='deg', lower=0.01, upper=179.9,
fix_final=fix_final_control)

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

Expand Down Expand Up @@ -186,6 +188,77 @@ def test_load_case_radau_to_lgl(self):
q.model.phase0.interp(xs=time_val, ys=theta_val, nodes='all'),
tolerance=1.0E-2)

def test_load_case_warn_fix_final_states(self):
import openmdao.api as om
from openmdao.utils.assert_utils import assert_warnings
import dymos as dm

p = setup_problem(dm.Radau(num_segments=20))

# Solve for the optimal trajectory
dm.run_problem(p)

# Load the solution
case = om.CaseReader('dymos_solution.db').get_case('final')

# create a problem with a different transcription with a different number of variables
q = setup_problem(dm.GaussLobatto(num_segments=50))

msgs = []

# Load the values from the previous solution
for state_name in ['x', 'y']:
msgs.append((UserWarning, f"phase0.states:{state_name} specifies 'fix_final=True'."
f" If the given restart file has a different final value"
f" this will overwrite the user-specified value"))

with assert_warnings(msgs):
dm.load_case(q, case)

def test_load_case_warn_fix_final_control(self):
import openmdao.api as om
from openmdao.utils.assert_utils import assert_warning
import dymos as dm
p = setup_problem(dm.Radau(num_segments=10))

# Solve for the optimal trajectory
dm.run_problem(p)

# Load the solution
case = om.CaseReader('dymos_solution.db').get_case('final')

# create a problem with a different transcription with a different number of variables
q = setup_problem(dm.Radau(num_segments=10), fix_final_state=False, fix_final_control=True)

msg = f"phase0.controls:theta specifies 'fix_final=True'. If the given restart file has a" \
f" different final value this will overwrite the user-specified value"

with assert_warning(UserWarning, msg):
dm.load_case(q, case)

def test_load_case_warn_fix_final_polynomial_control(self):
import openmdao.api as om
from openmdao.utils.assert_utils import assert_warning
import dymos as dm
p = setup_problem(dm.Radau(num_segments=10), polynomial_control=True,)

# Solve for the optimal trajectory
dm.run_problem(p)

# Load the solution
case = om.CaseReader('dymos_solution.db').get_case('final')

# create a problem with a different transcription with a different number of variables
q = setup_problem(dm.Radau(num_segments=10), polynomial_control=True,
fix_final_state=False, fix_final_control=True)

# Load the values from the previous solution
msg = f"phase0.polynomial_controls:theta specifies 'fix_final=True'. If the given restart file has a" \
f" different final value this will overwrite the user-specified value"

with assert_warning(UserWarning, msg):
dm.load_case(q, case)


if __name__ == '__main__': # pragma: no cover
unittest.main()

0 comments on commit fbbfe54

Please sign in to comment.