Skip to content

Commit

Permalink
Merge branch 'master' into docs
Browse files Browse the repository at this point in the history
  • Loading branch information
swryan committed Jun 25, 2020
2 parents 4fa8570 + 956f8fc commit 708ea16
Show file tree
Hide file tree
Showing 23 changed files with 18,958 additions and 604 deletions.
63 changes: 32 additions & 31 deletions .travis.yml
Expand Up @@ -13,11 +13,13 @@ language: generic

env:
matrix:
# test with the latest version of Python 3.x
- PY=3 NUMPY=1.18 SCIPY=1.4 PETSc=3.12 UPLOAD_DOCS=1 SNOPT_VERSION=7.7 PYOPTSPARSE_VERSION=v2.1.0
- PY=3 NUMPY=1.17 SCIPY=1.3 SNOPT_VERSION=7.2 PYOPTSPARSE_VERSION=v1.2
- PY=3.7 NUMPY=1.17 SCIPY=1.3 SNOPT_VERSION=7.7 PYOPTSPARSE_VERSION=v2.1.0
- PY=3.6 NUMPY=1.16 SCIPY=1.2 PETSc=3.10.2 SNOPT_VERSION=7.7 PYOPTSPARSE_VERSION=v2.1.0
# latest versions
- PY=3 NUMPY=1 SCIPY=1 PYOPTSPARSE=v2.1.0 SNOPT=7.7 PETSc=3
# baseline versions
- PY=3.8 NUMPY=1.18 SCIPY=1.4 PYOPTSPARSE=v2.1.0 SNOPT=7.7 PETSc=3.12 UPLOAD_DOCS=1
# older versions
- PY=3.7 NUMPY=1.17 SCIPY=1.3 PYOPTSPARSE=v2.1.0 SNOPT=7.7
- PY=3.6 NUMPY=1.16 SCIPY=1.2 PYOPTSPARSE=v1.2 SNOPT=7.2 PETSc=3.10.2

git:
depth: 99999
Expand Down Expand Up @@ -72,7 +74,7 @@ install:
echo "KEY NOT FOUND";
fi

# if we don't have a cached conda environment then build one, otherwise just activate the cached one
# build Python environment
- |
echo ">>> Building python environment";
echo " >> Installing conda";
Expand All @@ -87,46 +89,42 @@ install:
conda create --yes -n PY$PY python=$PY numpy=$NUMPY scipy=$SCIPY cython swig;
source $HOME/miniconda/bin/activate PY$PY;
echo " >> Installing non-pure Python dependencies from conda";
pip install --upgrade pip;
if [ "$PETSc" ]; then
echo "Installing PETSc";
echo " >> Installing PETSc";
conda install -c anaconda mpi4py --yes;
conda install -c conda-forge petsc=$PETSc petsc4py --yes;
fi
pip install --upgrade pip;
echo " >> Installing forked python packages";
pip install git+https://github.com/swryan/coveralls-python@work;
if [ "$PYOPTSPARSE" ]; then
echo " >> Installing pyOptSparse";
git clone -q https://github.com/OpenMDAO/build_pyoptsparse;
echo " >> Installing pyOptSparse";
git clone https://github.com/OpenMDAO/build_pyoptsparse;
cd build_pyoptsparse;
chmod 755 ./build_pyoptsparse.sh;
cd build_pyoptsparse;
chmod 755 ./build_pyoptsparse.sh;
echo " >> Checking SNOPT and PyoptSparse version"
if [[ "$SNOPT_VERSION" == "7.7" && "$PYOPTSPARSE_VERSION" == "v2.1.0" ]] || [[ "$SNOPT_VERSION" == "7.2" && "$PYOPTSPARSE_VERSION" == "v1.2" ]]; then
echo " >> Found SNOPT and PyoptSparse"
if [ "$SNOPT_VERSION" == "7.7" ] && [ "$SNOPT_LOCATION_77" ]; then
if [ "$SNOPT" == "7.7" ] && [ "$SNOPT_LOCATION_77" ]; then
echo " > Secure copying SNOPT 7.7 over SSH";
mkdir SNOPT;
scp -r "$SNOPT_LOCATION_77" SNOPT;
./build_pyoptsparse.sh -s SNOPT/src -b "$PYOPTSPARSE_VERSION";
scp -qr "$SNOPT_LOCATION_77" SNOPT;
./build_pyoptsparse.sh -b "$PYOPTSPARSE" -s SNOPT/src;
elif [ "$SNOPT_VERSION" == "7.2" ] && [ "$SNOPT_LOCATION_72" ]; then
elif [ "$SNOPT" == "7.2" ] && [ "$SNOPT_LOCATION_72" ]; then
echo " > Secure copying SNOPT 7.2 over SSH";
mkdir SNOPT;
scp -r "$SNOPT_LOCATION_72" SNOPT;
./build_pyoptsparse.sh -s SNOPT/source -b "$PYOPTSPARSE_VERSION";
scp -qr "$SNOPT_LOCATION_72" SNOPT;
./build_pyoptsparse.sh -b "$PYOPTSPARSE" -s SNOPT/source;
else
./build_pyoptsparse.sh -b "$PYOPTSPARSE_VERSION";
if [ "$SNOPT" ]; then
echo "SNOPT version $SNOPT was requested but source is not available";
fi
./build_pyoptsparse.sh -b "$PYOPTSPARSE";
fi
else
echo "Incompatible versions of SNOPT and PyoptSparse"
cd ..;
fi
cd ..;
echo " >> Installing optional packages for test coverage";
pip install psutil objgraph git+https://github.com/mdolab/pyxdsm;
Expand All @@ -145,7 +143,7 @@ script:
- export OMPI_MCA_btl=^openib
# newer versions of OpenMPI require this
- export OMPI_MCA_rmaps_base_oversubscribe=1
# IPOPT Requires
# IPOpt requires this
- export LD_LIBRARY_PATH=/home/travis/ipopt/lib

# make docs first
Expand All @@ -166,6 +164,9 @@ after_success:
# again, only run coverage operations on the upload machine after success.
# strip the site-package path so that links works on coveralls.io
- if [ "$UPLOAD_DOCS" ]; then
echo " >> Installing forked version of coveralls";
pip install git+https://github.com/swryan/coveralls-python@work;

coveralls --rcfile=../../.coveragerc --output=coveralls.json;
SITE=`python -c 'import site; print(site.getsitepackages()[0])'`;
sed "s/${SITE//\//\\/}\///g" < coveralls.json > coveralls-upd.json;
Expand All @@ -181,4 +182,4 @@ deploy:
python _utils/upload_doc_version.py;
fi
on:
branch: master
branch: master
4 changes: 2 additions & 2 deletions openmdao/components/add_subtract_comp.py
Expand Up @@ -79,8 +79,8 @@ def __init__(self, output_name=None, input_names=None, vec_size=1, length=1,
self._input_names = {}

if isinstance(output_name, str):
self.add_equation(output_name, input_names, vec_size, length, val, scaling_factors,
kwargs)
self.add_equation(output_name, input_names, vec_size, length, val,
scaling_factors=scaling_factors, **kwargs)
elif isinstance(output_name, collections.Iterable):
raise NotImplementedError(self.msginfo + ': Declaring multiple addition systems '
'on initiation is not implemented.'
Expand Down
24 changes: 22 additions & 2 deletions openmdao/components/exec_comp.py
Expand Up @@ -7,6 +7,7 @@

from openmdao.core.explicitcomponent import ExplicitComponent
from openmdao.utils.units import valid_units
from openmdao.utils.general_utils import warn_deprecation

# regex to check for variable names.
VAR_RGX = re.compile(r'([.]*[_a-zA-Z]\w*[ ]*\(?)')
Expand Down Expand Up @@ -132,6 +133,7 @@ def __init__(self, exprs=[], **kwargs):
exp(x) Exponential function
expm1(x) exp(x) - 1
factorial(x) Factorial of all numbers in x
(DEPRECATED, not available with SciPy >=1.5)
fmax(x, y) Element-wise maximum of x and y
fmin(x, y) Element-wise minimum of x and y
inner(x, y) Inner product of arrays x and y
Expand Down Expand Up @@ -634,8 +636,26 @@ def _import_functs(mod, dct, names=None):
except ImportError:
pass
else:
_import_functs(scipy.special, _expr_dict,
names=['factorial', 'erf', 'erfc'])
_import_functs(scipy.special, _expr_dict, names=['erf', 'erfc'])

from distutils.version import LooseVersion
if LooseVersion(scipy.__version__) >= LooseVersion("1.5.0"):
def factorial(*args):
"""
Raise a RuntimeError stating that the factorial function is not supported.
"""
raise RuntimeError("The 'factorial' function is not supported for SciPy "
f"versions >= 1.5, current version: {scipy.__version__}")
else:
def factorial(*args):
"""
Raise a warning stating that the factorial function is deprecated.
"""
warn_deprecation("The 'factorial' function is deprecated. "
"It is no longer supported for SciPy versions >= 1.5.")
return scipy.special.factorial(*args)

_expr_dict['factorial'] = factorial


# Put any functions here that need special versions to work under
Expand Down
51 changes: 51 additions & 0 deletions openmdao/components/tests/test_add_subtract_comp.py
Expand Up @@ -263,6 +263,57 @@ def test_partials(self):
assert_check_partials(partials)


class TestAddSubtractInit(unittest.TestCase):

def setUp(self):
self.nn = 5

self.p = om.Problem()

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

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

# verify proper handling of constructor args
adder = om.AddSubtractComp(output_name='adder_output',
input_names=['input_a', 'input_b', 'input_c'],
vec_size=self.nn, length=3,
scaling_factors=[2., 1., -1],
units='ft')

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

self.p.model.connect('a', 'add_subtract_comp.input_a')
self.p.model.connect('b', 'add_subtract_comp.input_b')
self.p.model.connect('c', 'add_subtract_comp.input_c')

self.p.setup()

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

self.p.run_model()

def test_results(self):
a = self.p['a']
b = self.p['b']
c = self.p['c']
out = self.p['add_subtract_comp.adder_output']
m_to_ft = 3.280839895
expected = 2*a + b*m_to_ft - c*m_to_ft
assert_near_equal(out, expected, 1e-8)

def test_partials(self):
partials = self.p.check_partials(method='fd', out_stream=None)
assert_check_partials(partials)


class TestForExceptions(unittest.TestCase):

def test_for_bad_scale_factors(self):
Expand Down
57 changes: 49 additions & 8 deletions openmdao/components/tests/test_exec_comp.py
Expand Up @@ -6,14 +6,16 @@
from numpy.testing import assert_almost_equal
import scipy

from distutils.version import LooseVersion

try:
from parameterized import parameterized
except ImportError:
from openmdao.utils.assert_utils import SkipParameterized as parameterized

import openmdao.api as om
from openmdao.components.exec_comp import _expr_dict
from openmdao.utils.assert_utils import assert_near_equal, assert_check_partials
from openmdao.utils.assert_utils import assert_near_equal, assert_check_partials, assert_warning

_ufunc_test_data = {
'abs': {
Expand Down Expand Up @@ -115,11 +117,6 @@
'check_func': np.expm1,
'args': {'f': {'value': np.zeros(6)},
'x': {'value': np.random.random(6)}}},
'factorial': {
'str': 'f=factorial(x)',
'check_func': scipy.special.factorial,
'args': {'f': {'value': np.zeros(6)},
'x': {'value': np.random.random(6)}}},
'fmax': {
'str': 'f=fmax(x, y)',
'check_func': np.fmax,
Expand Down Expand Up @@ -254,6 +251,28 @@
}


# 'factorial' will raise a RuntimeError or a deprecation warning depending on scipy version
if LooseVersion(scipy.__version__) >= LooseVersion("1.5.0"):
_ufunc_test_data['factorial'] = {
'str': 'f=factorial(x)',
'args': {'f': {'value': np.zeros(6)},
'x': {'value': np.random.random(6)}},
'error': (RuntimeError,
"The 'factorial' function is not supported for SciPy "
f"versions >= 1.5, current version: {scipy.__version__}")
}
else:
_ufunc_test_data['factorial'] = {
'str': 'f=factorial(x)',
'check_func': scipy.special.factorial,
'args': {'f': {'value': np.zeros(6)},
'x': {'value': np.random.random(6)}},
'warning': (DeprecationWarning,
"The 'factorial' function is deprecated. "
"It is no longer supported for SciPy versions >= 1.5.")
}


class TestExecComp(unittest.TestCase):

def test_no_expr(self):
Expand Down Expand Up @@ -1074,7 +1093,18 @@ def test_exec_comp_value(self, f):
model.add_subsystem('comp', om.ExecComp(test_data['str'], **test_data['args']),
promotes_outputs=['f'])
prob.setup()
prob.run_model()

if 'error' in test_data:
err, msg = test_data['error']
with self.assertRaises(err) as cm:
prob.run_model()
self.assertTrue(msg in str(cm.exception))
return
elif 'warning' in test_data:
with assert_warning(*test_data['warning']):
prob.run_model()
else:
prob.run_model()

if 'check_func' in test_data:
check_args = []
Expand Down Expand Up @@ -1121,7 +1151,18 @@ def test_exec_comp_jac(self, f):
om.ExecComp(test_data['str'], **test_data['args']),
promotes_outputs=['f'])
prob.setup()
prob.run_model()

if 'error' in test_data:
err, msg = test_data['error']
with self.assertRaises(err) as cm:
prob.run_model()
self.assertTrue(msg in str(cm.exception))
return
elif 'warning' in test_data:
with assert_warning(*test_data['warning']):
prob.run_model()
else:
prob.run_model()

if 'check_val' not in test_data:
cpd = prob.check_partials(out_stream=None)
Expand Down
13 changes: 8 additions & 5 deletions openmdao/utils/om.py
Expand Up @@ -44,6 +44,7 @@
split_ep, _compute_entry_points_setup_parser, _compute_entry_points_exec, \
_find_plugins_setup_parser, _find_plugins_exec
from openmdao.core.component import Component
from openmdao.utils.general_utils import warn_deprecation


def _n2_setup_parser(parser):
Expand All @@ -66,7 +67,7 @@ def _n2_setup_parser(parser):
action='store', dest='title', help='diagram title.')
parser.add_argument('--use_declare_partial_info', action='store_true',
dest='use_declare_partial_info',
help="use declare partial info for internal connectivity.")
help="ignored, now always true.")


def _n2_cmd(options, user_args):
Expand All @@ -87,10 +88,13 @@ def _n2_cmd(options, user_args):
def _noraise(prob):
prob.model._raise_connection_errors = False

if options.use_declare_partial_info:
warn_deprecation("'--use_declare_partial_info' is now the"
" default and the option is ignored.")

def _viewmod(prob):
n2(prob, outfile=options.outfile, show_browser=not options.no_browser,
title=options.title, embeddable=options.embeddable,
use_declare_partial_info=options.use_declare_partial_info)
title=options.title, embeddable=options.embeddable)
exit() # could make this command line selectable later

hooks._register_hook('setup', 'Problem', pre=_noraise)
Expand All @@ -100,8 +104,7 @@ def _viewmod(prob):
else:
# assume the file is a recording, run standalone
n2(filename, outfile=options.outfile, title=options.title,
show_browser=not options.no_browser, embeddable=options.embeddable,
use_declare_partial_info=options.use_declare_partial_info)
show_browser=not options.no_browser, embeddable=options.embeddable)


def _view_connections_setup_parser(parser):
Expand Down

0 comments on commit 708ea16

Please sign in to comment.