1 /*
2  *    This file is part of CasADi.
3  *
4  *    CasADi -- A symbolic framework for dynamic optimization.
5  *    Copyright (C) 2010-2014 Joel Andersson, Joris Gillis, Moritz Diehl,
6  *                            K.U. Leuven. All rights reserved.
7  *    Copyright (C) 2011-2014 Greg Horn
8  *
9  *    CasADi is free software; you can redistribute it and/or
10  *    modify it under the terms of the GNU Lesser General Public
11  *    License as published by the Free Software Foundation; either
12  *    version 3 of the License, or (at your option) any later version.
13  *
14  *    CasADi is distributed in the hope that it will be useful,
15  *    but WITHOUT ANY WARRANTY; without even the implied warranty of
16  *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
17  *    Lesser General Public License for more details.
18  *
19  *    You should have received a copy of the GNU Lesser General Public
20  *    License along with CasADi; if not, write to the Free Software
21  *    Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
22  *
23  */
24 
25 
26 #ifndef CASADI_SNOPT_INTERFACE_HPP
27 #define CASADI_SNOPT_INTERFACE_HPP
28 
29 #include "casadi/core/nlpsol_impl.hpp"
30 #include "casadi/core/im.hpp"
31 
32 #include "casadi/interfaces/snopt/casadi_nlpsol_snopt_export.h"
33 extern "C" {
34 #include "snopt_cwrap.h" // NOLINT(build/include)
35 }
36 
37 /** \defgroup plugin_Nlpsol_snopt
38   SNOPT interface
39 */
40 
41 /** \pluginsection{Nlpsol,snopt} */
42 
43 /// \cond INTERNAL
44 namespace casadi {
45 
46   // Forward declaration
47   class SnoptInterface;
48 
49   struct CASADI_NLPSOL_SNOPT_EXPORT SnoptMemory : public NlpsolMemory {
50     /// Function object
51     const SnoptInterface& self;
52 
53     // Current solution
54     double *xk2, *lam_gk, *lam_xk;
55 
56     // Current calculated quantities
57     double *gk, *jac_fk, *jac_gk;
58 
59     std::vector<double> bl, bu, xx;
60 
61     std::vector<int> hs, locJ, indJ;
62 
63     casadi_int n_iter; // number of major iterations
64 
65     std::vector<double> A_data, valJ, rc, pi;
66 
67     // Memory pool
68     static std::vector<SnoptMemory*> mempool;
69     int memind;
70 
71     int return_status;
72 
73     /// Constructor
74     SnoptMemory(const SnoptInterface& self);
75 
76     /// Destructor
77     ~SnoptMemory();
78   };
79 
80   /** \brief \pluginbrief{Nlpsol,snopt}
81      @copydoc Nlpsol_doc
82      @copydoc plugin_Nlpsol_snopt
83   */
84   class CASADI_NLPSOL_SNOPT_EXPORT SnoptInterface : public Nlpsol {
85   public:
86     // NLP functions
87     Sparsity jacf_sp_;
88     Sparsity jacg_sp_;
89 
90     // Constructor
91     explicit SnoptInterface(const std::string& name, const Function& nlp);
92 
93     // Destructor
94     ~SnoptInterface() override;
95 
96     // Get name of the plugin
plugin_name() const97     const char* plugin_name() const override { return "snopt";}
98 
99     // Get name of the class
class_name() const100     std::string class_name() const override { return "SnoptInterface";}
101 
102     /** \brief  Create a new NLP Solver */
creator(const std::string & name,const Function & nlp)103     static Nlpsol* creator(const std::string& name, const Function& nlp) {
104       return new SnoptInterface(name, nlp);
105     }
106 
107     ///@{
108     /** \brief Options */
109     static const Options options_;
get_options() const110     const Options& get_options() const override { return options_;}
111     ///@}
112 
113     // Initialize the solver
114     void init(const Dict& opts) override;
115 
116     /** \brief Create memory block */
alloc_mem() const117     void* alloc_mem() const override { return new SnoptMemory(*this);}
118 
119     /** \brief Initalize memory block */
120     int init_mem(void* mem) const override;
121 
122     /** \brief Free memory block */
free_mem(void * mem) const123     void free_mem(void *mem) const override { delete static_cast<SnoptMemory*>(mem);}
124 
125     /** \brief Set the (persistent) work vectors */
126     void set_work(void* mem, const double**& arg, double**& res,
127                           casadi_int*& iw, double*& w) const override;
128 
129     // Solve the NLP
130     int solve(void* mem) const override;
131 
132     /// Get all statistics
133     Dict get_stats(void* mem) const override;
134 
135     static std::map<int, std::string> status_;
136     static std::map<int, std::string> secondary_status_;
137 
138     std::string formatStatus(int status) const;
139     std::string formatSecondaryStatus(int status) const;
140 
141     void userfun(SnoptMemory* m, int* mode, int nnObj, int nnCon, int nnJac, int nnL, int neJac,
142                  const double* x, double* fObj, double*gObj, double* fCon, double* gCon,
143                  int nState, char* cu, int lencu, int* iu, int leniu, double* ru, int lenru) const;
144 
145     casadi_int nnJac_;
146     casadi_int nnObj_;
147     casadi_int nnCon_;
148 
149     IM A_structure_;
150 
151     casadi_int m_;
152     casadi_int iObj_;
153 
154     static void userfunPtr(int * mode, int* nnObj, int * nnCon, int *nJac, int *nnL, int * neJac, // NOLINT
155                            double *x, double *fObj, double *gObj, double * fCon, double* gCon, // NOLINT
156                            int* nState, char* cu, int* lencu, int* iu, int* leniu, // NOLINT
157                            double* ru, int *lenru); // NOLINT
158 
159     // Matrix A has a linear objective row
160     bool jacF_row_;
161     // Matrix A has a dummy row
162     bool dummyrow_;
163 
164     /// A documentation string
165     static const std::string meta_doc;
166 
167     /// Warm-start settings
168     casadi_int Cold_;
169 
170     double inf_;
171 
172 
173     /** \brief Serialize an object without type information */
174     void serialize_body(SerializingStream &s) const override;
175 
176     /** \brief Deserialize into MX */
deserialize(DeserializingStream & s)177     static ProtoFunction* deserialize(DeserializingStream& s) { return new SnoptInterface(s); }
178 
179   protected:
180     /** \brief Deserializing constructor */
181     explicit SnoptInterface(DeserializingStream& s);
182 
183   private:
184       // options
185       Dict opts_;
186   };
187 
188 } // namespace casadi
189 
190 /// \endcond
191 #endif // CASADI_SNOPT_INTERFACE_HPP
192