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