mdolab / pyoptsparse

pyOptSparse is an object-oriented framework for formulating and solving nonlinear constrained optimization problems in an efficient, reusable, and portable manner.
https://mdolab-pyoptsparse.readthedocs-hosted.com/en/latest/
GNU Lesser General Public License v3.0
228 stars 109 forks source link

Cannot run ParOpt using OpenMDAO pyoptsparse driver #96

Closed aaronyicongfu closed 4 years ago

aaronyicongfu commented 4 years ago

Type of issue

Description

Hi, I am trying to run the "helloworld" paraboloid example on openmdao's homepage, but instead of using the ScipyOptimizeDriver, I would like to use pyOptSparseDriver with ParOpt as optimizer by adding two lines (and comment out the ScipyOptimizeDriver):

prob.driver = om.pyOptSparseDriver()
prob.driver.options['optimizer'] = 'ParOpt' 

And I got the following error:

Traceback (most recent call last):
  File "paraboloid-min.py", line 16, in <module>
    prob.driver.options['optimizer'] = 'ParOpt'
  File "/usr/local/lib/python3.7/site-packages/openmdao/utils/options_dictionary.py", line 425, in __setitem__
    self._assert_valid(name, value)
  File "/usr/local/lib/python3.7/site-packages/openmdao/utils/options_dictionary.py", line 248, in _assert_valid
    ValueError)
  File "/usr/local/lib/python3.7/site-packages/openmdao/utils/options_dictionary.py", line 217, in _raise
    raise exc_type(full_msg)
ValueError: pyOptSparseDriver: Value ('ParOpt') of option 'optimizer' is not one of ['ALPSO', 'CONMIN', 'FSQP', 'IPOPT', 'NLPQLP', 'NSGA2', 'PSQP', 'SLSQP', 'SNOPT', 'NLPY_AUGLAG', 'NOMAD'].

It seems that for some reason for my openmdao implementation, ParOpt is not in the available optimizer list. I also tried to manually add 'ParOpt' to the list and I got this:

Traceback (most recent call last):
  File "/usr/local/lib/python3.7/site-packages/openmdao/drivers/pyoptsparse_driver.py", line 358, in run
    opt = getattr(_tmp, optimizer)()
TypeError: 'module' object is not callable

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "paraboloid-min.py", line 23, in <module>
    prob.run_driver()
  File "/usr/local/lib/python3.7/site-packages/openmdao/core/problem.py", line 549, in run_driver
    return self.driver.run()
  File "/usr/local/lib/python3.7/site-packages/openmdao/drivers/pyoptsparse_driver.py", line 364, in run
    raise ImportError(msg)
ImportError: Optimizer ParOpt is not available in this installation.

But instead, I am able to run examples/hs015.py with --opt=paropt without errors, which means both pyoptsparse and ParOpt are installed correctly. I can also run the openmdao paraboloid problem using pyoptsparse driver with other optimziers such as ALPSO, NSGA2 and SLSQP. Could anyone help to identify what goes wrong here? Thank you very much!

Code version

openmdao: 3.0.0 (installed by pip install openmdao) pyoptsparse: 2.0.3

FYI, cc @gjkennedy

ewu63 commented 4 years ago

Can you try with the following modification to pyoptsparse/__init__.py? Line 22 should be from .pyParOpt.ParOpt import ParOpt instead of from .pyParOpt import ParOpt This is an issue on the pyOptSparse side which I will address soon.

Of course, the modifications you made to OpenMDAO has to be there also. @JustinSGray the driver should probably be modified to include the optimizer ParOpt, now that it's included in pyOptSparse.

aaronyicongfu commented 4 years ago

Thanks Neil @nwu63 for the rapid response! I added 'ParOpt' to both

grad_drivers = {'CONMIN', 'FSQP', 'IPOPT', 'NLPQLP', 'PSQP', 'SLSQP', 'SNOPT', 'NLPY_AUGLAG', 'ParOpt'}

and

optlist = ['ALPSO', 'CONMIN', 'FSQP', 'IPOPT', 'NLPQLP', 'NSGA2', 'PSQP', 'SLSQP', 'SNOPT', 'NLPY_AUGLAG', 'NOMAD', 'ParOpt']

in openmdao/drivers/pyoptsparse_driver.py, and modified the __init__.py as you mentioned. But I got this:

Traceback (most recent call last):
  File "paraboloid-min.py", line 23, in <module>
    prob.run_driver()
  File "/usr/local/lib/python3.7/site-packages/openmdao/core/problem.py", line 549, in run_driver
    return self.driver.run()
  File "/usr/local/lib/python3.7/site-packages/openmdao/drivers/pyoptsparse_driver.py", line 396, in run
    storeHistory=self.hist_file, hotStart=self.hotstart_file)
  File "/Users/aaronfu/packages/pyoptsparse/pyoptsparse/pyParOpt/ParOpt.py", line 309, in __call__
    multipliers=-z)
TypeError: bad operand type for unary -: 'NoneType'
ewu63 commented 4 years ago

I've made the same modifications locally, and the paraboloid example ran just fine for me. I guess the error is saying that z is None somehow? I'm not familiar with the ParOpt wrapper so I'm not exactly sure. You may have to do some debugging to see if the issue is on the OpenMDAO side or pyOptSparse side.

gjkennedy commented 4 years ago

So ParOpt returns None when the multiplier vector is empty, rather than an empty array.

We should modify the pyParOpt wrapper to deal with the None return and set the multiplier array to be an empty list.


From: Neil Wu notifications@github.com Sent: Tuesday, April 28, 2020 9:24 AM To: mdolab/pyoptsparse pyoptsparse@noreply.github.com Cc: Kennedy, Graeme J graeme.kennedy@aerospace.gatech.edu; Mention mention@noreply.github.com Subject: Re: [mdolab/pyoptsparse] Cannot run ParOpt using OpenMDAO pyoptsparse driver (#96)

I've made the same modifications locally, and the paraboloid example ran just fine for me. I guess the error is saying that z is None somehow? I'm not familiar with the ParOpt wrapper so I'm not exactly sure. You may have to do some debugging to see if the issue is on the OpenMDAO side or pyOptSparse side.

— You are receiving this because you were mentioned. Reply to this email directly, view it on GitHubhttps://github.com/mdolab/pyoptsparse/issues/96#issuecomment-620605448, or unsubscribehttps://github.com/notifications/unsubscribe-auth/ACCBPTU6JDRDVTW52RNVCADRO3KIVANCNFSM4MSOR64Q.

aaronyicongfu commented 4 years ago

Dr. Kennedy, the changes are submitted in pull request #98 @gjkennedy