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_DAE_BUILDER_HPP
27 #define CASADI_DAE_BUILDER_HPP
28 
29 #include "variable.hpp"
30 
31 namespace casadi {
32 
33   // Forward declarations
34   class XmlNode;
35 
36   /** \brief An initial-value problem in differential-algebraic equations
37       <H3>Independent variables:  </H3>
38       \verbatim
39       t:      time
40       \endverbatim
41 
42       <H3>Time-continuous variables:  </H3>
43       \verbatim
44       x:      states defined by ODE
45       s:      implicitly defined states
46       z:      algebraic variables
47       u:      control signals
48       q:      quadrature states
49       y:      outputs
50       \endverbatim
51 
52       <H3>Time-constant variables:  </H3>
53       \verbatim
54       p:      free parameters
55       d:      dependent parameters
56       \endverbatim
57 
58       <H3>Dynamic constraints (imposed everywhere):  </H3>
59       \verbatim
60       ODE                    \dot{x} ==  ode(t, x, s, z, u, p, d)
61       DAE or implicit ODE:         0 ==  dae(t, x, s, z, u, p, d, sdot)
62       algebraic equations:         0 ==  alg(t, x, s, z, u, p, d)
63       quadrature equations:  \dot{q} == quad(t, x, s, z, u, p, d)
64       dependent parameters:        d == ddef(t, x, s, z, u, p, d)
65       output equations:            y == ydef(t, x, s, z, u, p, d)
66       \endverbatim
67 
68       <H3>Point constraints (imposed pointwise):  </H3>
69       \verbatim
70       Initial equations:           0 == init(t, x, s, z, u, p, d, sdot)
71       \endverbatim
72 
73       \date 2012-2015
74       \author Joel Andersson
75   */
76   class CASADI_EXPORT DaeBuilder
77     : public SWIG_IF_ELSE(PrintableCommon, Printable<DaeBuilder>) {
78   public:
79 
80     /// Default constructor
81     DaeBuilder();
82 
83     /** @name Variables and equations
84      *  Public data members
85      */
86     ///@{
87     /** \brief Independent variable (usually time) */
88     MX t;
89 
90     /** \brief Differential states defined by ordinary differential equations (ODE)
91      */
92     std::vector<MX> x, ode, lam_ode;
93 
94     /** \brief Differential-algebraic equation (DAE) with corresponding state vector,
95      * state derivatives.
96      */
97     std::vector<MX> s, sdot, dae, lam_dae;
98 
99     /** \brief Algebraic equations and corresponding algebraic variables
100      * \a alg and \a z have matching dimensions and
101      * <tt>0 == alg(z, ...)</tt> implicitly defines \a z.
102      */
103     std::vector<MX> z, alg, lam_alg;
104 
105     /** \brief Quadrature states
106      * Quadrature states are defined by ODEs whose state does not enter in the right-hand-side.
107      */
108     std::vector<MX> q, quad, lam_quad;
109 
110 
111     /** \brief Local variables and corresponding definitions
112      */
113     std::vector<MX> w, wdef, lam_wdef;
114 
115     /** \brief Output variables and corresponding definitions
116      */
117     std::vector<MX> y, ydef, lam_ydef;
118 
119     /** \brief Free controls
120      * The trajectories of the free controls are decision variables of the optimal control problem.
121      * They are chosen by the optimization algorithm in order to minimize the cost functional.
122      */
123     std::vector<MX> u;
124 
125     /** \brief Parameters
126      * A parameter is constant over time, but whose value is chosen by e.g. an
127      * optimization algorithm.
128      */
129     std::vector<MX> p;
130 
131     /** \brief Named constants */
132     std::vector<MX> c, cdef;
133 
134     /** \brief Dependent parameters and corresponding definitions
135      * Interdependencies are allowed but must be non-cyclic.
136      */
137     std::vector<MX> d, ddef, lam_ddef;
138     ///@}
139 
140     /** \brief Auxiliary variables: Used e.g. to define functions */
141     std::vector<MX> aux;
142 
143     /** \brief Initial conditions
144      * At <tt>t==0</tt>, <tt>0 == init(sdot, s, ...)</tt> holds in addition to
145      * the ode and/or dae.
146      */
147     std::vector<MX> init;
148     ///@}
149 
150     /** @name Symbolic modeling
151      *  Formulate an optimal control problem
152      */
153     ///@{
154     /// Add a new parameter
155     MX add_p(const std::string& name=std::string(), casadi_int n=1);
156 
157     /// Add a new control
158     MX add_u(const std::string& name=std::string(), casadi_int n=1);
159 
160     /// Add a new differential state
161     MX add_x(const std::string& name=std::string(), casadi_int n=1);
162 
163     /// Add a implicit state
164     std::pair<MX, MX> add_s(const std::string& name=std::string(), casadi_int n=1);
165 
166     /// Add a new algebraic variable
167     MX add_z(const std::string& name=std::string(), casadi_int n=1);
168 
169     /// Add a new quadrature state
170     MX add_q(const std::string& name=std::string(), casadi_int n=1);
171 
172     /// Add a new dependent parameter
173     MX add_d(const std::string& name, const MX& new_ddef);
174 
175     /// Add a new output
176     MX add_y(const std::string& name, const MX& new_ydef);
177 
178     /// Add an ordinary differential equation
179     void add_ode(const std::string& name, const MX& new_ode);
180 
181     /// Add a differential-algebraic equation
182     void add_dae(const std::string& name, const MX& new_dae);
183 
184     /// Add an algebraic equation
185     void add_alg(const std::string& name, const MX& new_alg);
186 
187     /// Add a quadrature equation
188     void add_quad(const std::string& name, const MX& new_quad);
189 
190     /// Add an auxiliary variable
191     MX add_aux(const std::string& name=std::string(), casadi_int n=1);
192 
193     /// Check if dimensions match
194     void sanity_check() const;
195     ///@}
196 
197     /** @name Manipulation
198      *  Reformulate the dynamic optimization problem.
199      */
200     ///@{
201 
202     /// Identify and separate the algebraic variables and equations in the DAE
203     void split_dae();
204 
205     /// Eliminate algebraic variables and equations transforming them into outputs
206     void eliminate_alg();
207 
208     /// Transform the implicit DAE to a semi-explicit DAE
209     void make_semi_explicit();
210 
211     /// Transform the implicit DAE or semi-explicit DAE into an explicit ODE
212     void make_explicit();
213 
214     /// Sort dependent parameters
215     void sort_d();
216 
217     /// Eliminate interdependencies amongst dependent parameters
218     void split_d();
219 
220     /// Eliminate dependent parameters
221     void eliminate_d();
222 
223     /// Eliminate quadrature states and turn them into ODE states
224     void eliminate_quad();
225 
226     /// Sort the DAE and implicitly defined states
227     void sort_dae();
228 
229     /// Sort the algebraic equations and algebraic states
230     void sort_alg();
231 
232     /// Scale the variables
233     void scale_variables();
234 
235     /// Scale the implicit equations
236     void scale_equations();
237     ///@}
238 
239     /** @name Functions
240      *  Add or load auxiliary functions
241      */
242     ///@{
243 
244     /// Add a function from loaded expressions
245     Function add_fun(const std::string& name,
246                      const std::vector<std::string>& arg,
247                      const std::vector<std::string>& res, const Dict& opts=Dict());
248 
249     /// Add an already existing function
250     Function add_fun(const Function& f);
251 
252     /// Add an external function
253     Function add_fun(const std::string& name, const Importer& compiler,
254                      const Dict& opts=Dict());
255 
256     /// Does a particular function already exist?
257     bool has_fun(const std::string& name) const;
258 
259     /// Get function by name
260     Function fun(const std::string& name) const;
261   ///@}
262 
263     /** @name Import and export
264      */
265     ///@{
266     /// Import existing problem from FMI/XML
267     void parse_fmi(const std::string& filename);
268 
269 #ifndef SWIG
270     // Input convension in codegen
271     enum DaeBuilderIn {
272       DAE_BUILDER_T,
273       DAE_BUILDER_C,
274       DAE_BUILDER_P,
275       DAE_BUILDER_D,
276       DAE_BUILDER_U,
277       DAE_BUILDER_X,
278       DAE_BUILDER_S,
279       DAE_BUILDER_SDOT,
280       DAE_BUILDER_Z,
281       DAE_BUILDER_Q,
282       DAE_BUILDER_W,
283       DAE_BUILDER_Y,
284       DAE_BUILDER_NUM_IN
285     };
286 
287     // Output convension in codegen
288     enum DaeBuilderOut {
289       DAE_BUILDER_DDEF,
290       DAE_BUILDER_WDEF,
291       DAE_BUILDER_ODE,
292       DAE_BUILDER_DAE,
293       DAE_BUILDER_ALG,
294       DAE_BUILDER_QUAD,
295       DAE_BUILDER_YDEF,
296       DAE_BUILDER_NUM_OUT
297     };
298 
299     // Get string representation for input, given enum
300     static std::string name_in(DaeBuilderIn ind);
301 
302     // Get string representation for all inputs
303     static std::string name_in();
304 
305     // Get enum representation for input, given string
306     static DaeBuilderIn enum_in(const std::string& id);
307 
308     // Get enum representation for input, given vector of strings
309     static std::vector<DaeBuilderIn> enum_in(const std::vector<std::string>& id);
310 
311     // Get string representation for output, given enum
312     static std::string name_out(DaeBuilderOut ind);
313 
314     // Get string representation for all outputs
315     static std::string name_out();
316 
317     // Get enum representation for output, given string
318     static DaeBuilderOut enum_out(const std::string& id);
319 
320     // Get enum representation for output, given vector of strings
321     static std::vector<DaeBuilderOut> enum_out(const std::vector<std::string>& id);
322 
323     // Get input expression, given enum
324     std::vector<MX> input(DaeBuilderIn ind) const;
325 
326     // Get output expression, given enum
327     std::vector<MX> output(DaeBuilderOut ind) const;
328 
329     // Get input expression, given enum
330     std::vector<MX> input(std::vector<DaeBuilderIn>& ind) const;
331 
332     // Get output expression, given enum
333     std::vector<MX> output(std::vector<DaeBuilderOut>& ind) const;
334 
335     // Get multiplier corresponding to an output expression, given enum
336     std::vector<MX> multiplier(DaeBuilderOut ind) const;
337 #endif // SWIG
338 
339     /// Add a named linear combination of output expressions
340     MX add_lc(const std::string& name,
341               const std::vector<std::string>& f_out);
342 
343     /// Construct a function object
344     Function create(const std::string& fname,
345                     const std::vector<std::string>& s_in,
346                     const std::vector<std::string>& s_out) const;
347     ///@}
348 
349     /// Get variable expression by name
350     MX var(const std::string& name) const;
351 
352     /// Get variable expression by name
operator ()(const std::string & name) const353     MX operator()(const std::string& name) const {return var(name);}
354 
355     /// Get a derivative expression by name
356     MX der(const std::string& name) const;
357 
358     /// Get a derivative expression by non-differentiated expression
359     MX der(const MX& var) const;
360 
361     /// Get the nominal value by name
362     double nominal(const std::string& name) const;
363 
364     /// Get the nominal value(s) by expression
365     std::vector<double> nominal(const MX& var) const;
366 
367     /// Set the nominal value by name
368     void set_nominal(const std::string& name, double val);
369 
370     /// Set the nominal value(s) by expression
371     void set_nominal(const MX& var, const std::vector<double>& val);
372 
373     /// Get the lower bound by name
374     double min(const std::string& name, bool normalized=false) const;
375 
376     /// Get the lower bound(s) by expression
377     std::vector<double> min(const MX& var, bool normalized=false) const;
378 
379     /// Set the lower bound by name
380     void set_min(const std::string& name, double val, bool normalized=false);
381 
382     /// Set the lower bound(s) by expression
383     void set_min(const MX& var, const std::vector<double>& val, bool normalized=false);
384 
385     /// Get the upper bound by name
386     double max(const std::string& name, bool normalized=false) const;
387 
388     /// Get the upper bound(s) by expression
389     std::vector<double> max(const MX& var, bool normalized=false) const;
390 
391     /// Set the upper bound by name
392     void set_max(const std::string& name, double val, bool normalized=false);
393 
394     /// Set the upper bound(s) by expression
395     void set_max(const MX& var, const std::vector<double>& val, bool normalized=false);
396 
397     /// Get the initial guess by name
398     double guess(const std::string& name, bool normalized=false) const;
399 
400     /// Get the initial guess(es) by expression
401     std::vector<double> guess(const MX& var, bool normalized=false) const;
402 
403     /// Set the initial guess by name
404     void set_guess(const std::string& name, double val, bool normalized=false);
405 
406     /// Set the initial guess(es) by expression
407     void set_guess(const MX& var, const std::vector<double>& val, bool normalized=false);
408 
409     /// Get the (optionally normalized) value at time 0 by name
410     double start(const std::string& name, bool normalized=false) const;
411 
412     /// Get the (optionally normalized) value(s) at time 0 by expression
413     std::vector<double> start(const MX& var, bool normalized=false) const;
414 
415     /// Set the (optionally normalized) value at time 0 by name
416     void set_start(const std::string& name, double val, bool normalized=false);
417 
418     /// Set the (optionally normalized) value(s) at time 0 by expression
419     void set_start(const MX& var, const std::vector<double>& val, bool normalized=false);
420 
421     /// Get the (optionally normalized) derivative value at time 0 by name
422     double derivative_start(const std::string& name, bool normalized=false) const;
423 
424     /// Get the (optionally normalized) derivative value(s) at time 0 by expression
425     std::vector<double> derivative_start(const MX& var, bool normalized=false) const;
426 
427     /// Set the (optionally normalized) derivative value at time 0 by name
428     void set_derivative_start(const std::string& name, double val, bool normalized=false);
429 
430     /// Set the (optionally normalized) derivative value(s) at time 0 by expression
431     void set_derivative_start(const MX& var, const std::vector<double>& val, bool normalized=false);
432 
433     /// Get the unit for a component
434     std::string unit(const std::string& name) const;
435 
436     /// Get the unit given a vector of symbolic variables (all units must be identical)
437     std::string unit(const MX& var) const;
438 
439     /// Set the unit for a component
440     void set_unit(const std::string& name, const std::string& val);
441 
442     /// Readable name of the class
type_name() const443     std::string type_name() const {return "DaeBuilder";}
444 
445     ///  Print representation
446     void disp(std::ostream& stream, bool more=false) const;
447 
448     /// Get string representation
get_str(bool more=false) const449     std::string get_str(bool more=false) const {
450       std::stringstream ss;
451       disp(ss, more);
452       return ss.str();
453     }
454 
455     /// Add a variable
456     void add_variable(const std::string& name, const Variable& var);
457 
458     /// Add a new variable: returns corresponding symbolic expression
459     MX add_variable(const std::string& name, casadi_int n=1);
460 
461     /// Add a new variable: returns corresponding symbolic expression
462     MX add_variable(const std::string& name, const Sparsity& sp);
463 
464     ///@{
465     /// Access a variable by name
466     Variable& variable(const std::string& name);
467     const Variable& variable(const std::string& name) const;
468     ///@}
469 
470 #ifndef SWIG
471     // Internal methods
472   protected:
473 
474     /// Get the qualified name
475     static std::string qualified_name(const XmlNode& nn);
476 
477     /// Find of variable by name
478     typedef std::map<std::string, Variable> VarMap;
479     VarMap varmap_;
480 
481     /// Linear combinations of output expressions
482     std::map<std::string, MX> lin_comb_;
483 
484     /** \brief Functions */
485     std::vector<Function> fun_;
486 
487     /// Read an equation
488     MX read_expr(const XmlNode& node);
489 
490     /// Read a variable
491     Variable& read_variable(const XmlNode& node);
492 
493     /// Get an attribute by expression
494     typedef double (DaeBuilder::*getAtt)(const std::string& name, bool normalized) const;
495     std::vector<double> attribute(getAtt f, const MX& var, bool normalized) const;
496 
497     /// Get a symbolic attribute by expression
498     typedef MX (DaeBuilder::*getAttS)(const std::string& name) const;
499     MX attribute(getAttS f, const MX& var) const;
500 
501     /// Set an attribute by expression
502     typedef void (DaeBuilder::*setAtt)(const std::string& name, double val, bool normalized);
503     void set_attribute(setAtt f, const MX& var, const std::vector<double>& val, bool normalized);
504 
505     /// Set a symbolic attribute by expression
506     typedef void (DaeBuilder::*setAttS)(const std::string& name, const MX& val);
507     void set_attribute(setAttS f, const MX& var, const MX& val);
508 
509 #endif // SWIG
510 
511   };
512 
513 } // namespace casadi
514 
515 #endif // CASADI_DAE_BUILDER_HPP
516