The first step when solving an optimization problem is to formulate a model and an optimization specification and then compile the model as described in the following sections in this chapter. There are four different optimization algorithms available in JModelica.org, which are suitable for different classes of optimization problems.
Dynamic optimization of DAEs using direct collocation with JMUs. This algorithm is the default algorithm for solving optimal control and parameter estimation problems. It is implemented in C, uses CppAD for computing function derivatives and IPOPT for solving the resulting NLP. Functions and records in models are supported by this algorithm. Use this method if your model is a DAE and does not contain discontinuities.
Dynamic optimization of DAEs using direct collocation with CasADi. This algorithm solves optimal control and parameter estimation problems. It is implemented in Python, uses CasADi for computing function derivatives and IPOPT for solving the resulting NLP. Only regular equations in models are supported currently. Use this method if you would like to test the future default collocation algorithm in JModelica.org and if your model is a continuous time DAE that does not contain functions or records. Note that this algorithm offers significantly increased performance as compared to the default algorithm.
Pseudospectral optimization of ODEs using CasADi. This algorithm solves optimal control problems with multiple phases using a pseudospectral method. It is implemented in Python, uses CasADi for computing function derivatives and IPOPT for solving the resulting NLP. Use this algorithm if your model is a continuous time ODE that contains multiple phases.
Derivative free calibration and optimization of ODEs with JMUs. This algorithm solves parameter optimization and model calibration problems and is based on FMUs. The algorithm is implemented in Python and relies on a Nelder-Mead derivative free optimization algorithm. Use this method if your model is of large scale and/or contains discontinuities or hybrid elements. Note that this algorithm is applicable to models which have been exported as FMUs also by other tools than JModelica.org.
To illustrate how to solve optimization problems the Van der Pol problem presented above is used. First, the model is compiled and loaded:
model_name = compile_jmu("VDP_Opt","VDP.mo")
model = JMUModel(model_name)
In this case, a JMU is compiled, corresponding compilation functions are available for XML-based models required by the CasADi-based
algorithms and for compilation of FMUs. All operations that can be performed on the model are available as methods of the
model object and can be accessed by tab completion. Invoking an optimization algorithm is done by calling the method JMUModel.optimize, which performs the following tasks:
Sets up the selected algorithm with default or user defined options
Invokes the algorithm to find a numerical solution to the problem
Writes the result to file
Returns a result object from which the solution can be retrieved
The interactive help for the optimize method is displayed by the command:
>>> help(model.optimize)
Solve an optimization problem.
Parameters::
algorithm --
The algorithm which will be used for the optimization is
specified by passing the algorithm class name as string or
class object in this argument. 'algorithm' can be any
class which implements the abstract class AlgorithmBase
(found in algorithm_drivers.py). In this way it is
possible to write custom algorithms and to use them with this
function.
The following algorithms are available:
- 'CollocationLagrangePolynomialsAlg'. This algorithm is based on
direct collocation on finite elements and the algorithm IPOPT
is used to obtain a numerical solution to the problem.
Default: 'CollocationLagrangePolynomialsAlg'
options --
The options that should be used in the algorithm. The options
documentation can be retrieved from an options object:
>>> myModel = JMUModel(...)
>>> opts = myModel.optimize_options()
>>> opts?
Valid values are:
- A dict that overrides some or all of the default values
provided by CollocationLagrangePolynomialsAlgOptions. An empty
dict will thus give all options with default values.
- A CollocationLagrangePolynomialsAlgOptions object.
Default: Empty dict
Returns::
A result object, subclass of algorithm_drivers.ResultBase.
Again, note that the parameters differs for different model classes. The optimize method can be invoked without any arguments, which case the default optimization algorithm, with default options, is invoked:
res = vdp.optimize()
In the remainder of this chapter the available algorithms are described in detail. Options for an algorithm can be set using
the options argument to the optimize method. It is convenient to first obtain an options object in order to access the documentation and default option values.
This is done by invoking the method optimize_options:
>>> help(m.optimize_options)
Returns an instance of the optimize options class containing options
default values. If called without argument then the options class for
the default optimization algorithm will be returned.
Parameters::
algorithm --
The algorithm for which the options class should be returned.
Possible values are: 'CollocationLagrangePolynomialsAlg'.
Default: 'CollocationLagrangePolynomialsAlg'
Returns::
Options class for the algorithm specified with default values.
The option object is essentially a Python dictionary and options are set simply by using standard dictionary syntax:
opts = vpd.optimize_options()
opts['n_e'] = 5
The optimization algorithm may then be invoked again with the new options:
res = vdp.optimize(options=opts)
Available options for each algorithm are documented in their respective sections in this Chapter.
The optimize method returns a result object containing the optimization result and some meta information about the solution. The most
common operation is to retrieve variable trajectories from the result object:
time = res['time'] x1 = res['x1']
Variable data is returned as numpy arrays in case of variables and as numeric values in the case of parameters. The result object also contains references to the model that was optimized, the name of the result file that was written to disk, a solver object representing the optimization algorithm and an options object that as used when solving the optimization problem.