ipopt_solver.cc
Go to the documentation of this file.
00001 /******************************************************************************
00002 Copyright (c) 2017, Alexander W. Winkler, ETH Zurich. All rights reserved.
00003 
00004 Redistribution and use in source and binary forms, with or without modification,
00005 are permitted provided that the following conditions are met:
00006     * Redistributions of source code must retain the above copyright notice,
00007       this list of conditions and the following disclaimer.
00008     * Redistributions in binary form must reproduce the above copyright notice,
00009       this list of conditions and the following disclaimer in the documentation
00010       and/or other materials provided with the distribution.
00011     * Neither the name of ETH ZURICH nor the names of its contributors may be
00012       used to endorse or promote products derived from this software without
00013       specific prior written permission.
00014 
00015 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
00016 ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
00017 WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
00018 DISCLAIMED. IN NO EVENT SHALL ETH ZURICH BE LIABLE FOR ANY DIRECT, INDIRECT,
00019 INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
00020 LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
00021 PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
00022 LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
00023 OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
00024 ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
00025 ******************************************************************************/
00026 
00027 #include <ifopt/ipopt_solver.h>
00028 #include <ifopt/ipopt_adapter.h>
00029 
00030 namespace ifopt {
00031 
00032 IpoptSolver::IpoptSolver()
00033 {
00034   ipopt_app_ = std::make_shared<Ipopt::IpoptApplication>();
00035   status_ = Ipopt::Solve_Succeeded;
00036 
00037   /* Which linear solver to use. Mumps is default because it comes with the
00038    * precompiled ubuntu binaries. However, the coin-hsl solvers can be
00039    * significantly faster and are free for academic purposes. They can be
00040    * downloaded here: http://www.hsl.rl.ac.uk/ipopt/ and must be compiled
00041    * into your IPOPT libraries. Then you can use the additional strings:
00042    * "ma27, ma57, ma77, ma86, ma97" here.
00043    */
00044   SetOption("linear_solver", "mumps");
00045 
00046   /* whether to use the analytical derivatives "exact" coded in ifopt, or let
00047    * IPOPT approximate these through "finite difference-values". This is usually
00048    * significantly slower.
00049    */
00050   SetOption("jacobian_approximation", "exact");
00051   SetOption("hessian_approximation", "limited-memory");
00052   SetOption("max_cpu_time", 40.0);
00053   SetOption("tol", 0.001);
00054   SetOption("print_timing_statistics", "no");
00055   SetOption("print_user_options", "no");
00056   SetOption("print_level", 4);
00057 
00058   // SetOption("max_iter", 1);
00059   // SetOption("derivative_test", "first-order");
00060   // SetOption("derivative_test_tol", 1e-3);
00061 }
00062 
00063 void
00064 IpoptSolver::Solve (Problem& nlp)
00065 {
00066   using namespace Ipopt;
00067 
00068   status_ = ipopt_app_->Initialize();
00069   if (status_ != Solve_Succeeded) {
00070     std::cout << std::endl << std::endl << "*** Error during initialization!" << std::endl;
00071     throw std::length_error("Ipopt could not initialize correctly");
00072   }
00073 
00074   // check the jacobian_approximation method
00075   std::string jac_type = "";
00076   ipopt_app_->Options()->GetStringValue("jacobian_approximation", jac_type, "");
00077   bool finite_diff = jac_type=="finite-difference-values";
00078 
00079   // convert the NLP problem to Ipopt
00080   SmartPtr<TNLP> nlp_ptr = new IpoptAdapter(nlp,finite_diff);
00081   status_ = ipopt_app_->OptimizeTNLP(nlp_ptr);
00082 
00083   if (status_ != Solve_Succeeded) {
00084     std::string msg = "ERROR: Ipopt failed to find a solution. Return Code: " + std::to_string(status_) + "\n";
00085     std::cerr << msg;
00086   }
00087 }
00088 
00089 void
00090 IpoptSolver::SetOption (const std::string& name, const std::string& value)
00091 {
00092   ipopt_app_->Options()->SetStringValue(name, value);
00093 }
00094 
00095 void
00096 IpoptSolver::SetOption (const std::string& name, int value)
00097 {
00098   ipopt_app_->Options()->SetIntegerValue(name, value);
00099 }
00100 
00101 void
00102 IpoptSolver::SetOption (const std::string& name, double value)
00103 {
00104   ipopt_app_->Options()->SetNumericValue(name, value);
00105 }
00106 
00107 double
00108 IpoptSolver::GetTotalWallclockTime ()
00109 {
00110   return ipopt_app_->Statistics()->TotalWallclockTime();
00111 }
00112 
00113 int
00114 IpoptSolver::GetReturnStatus ()
00115 {
00116   return status_;
00117 }
00118 
00119 } /* namespace ifopt */


ifopt
Author(s): Alexander W. Winkler
autogenerated on Sat May 18 2019 02:43:08