dae_builder_internal.hpp
1 /*
2  * This file is part of CasADi.
3  *
4  * CasADi -- A symbolic framework for dynamic optimization.
5  * Copyright (C) 2010-2023 Joel Andersson, Joris Gillis, Moritz Diehl,
6  * KU 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_INTERNAL_HPP
27 #define CASADI_DAE_BUILDER_INTERNAL_HPP
28 
29 #include <unordered_map>
30 
31 #include "dae_builder.hpp"
32 #include "shared_object_internal.hpp"
33 #include "casadi_enum.hpp"
34 
35 namespace casadi {
36 
37 // Forward declarations
38 struct XmlNode;
39 
42 
46 
49 
52 
55 
56 // Attributes
58 
59 // Permitted dependenciesKind values
61 
68 struct CASADI_EXPORT Variable {
69  friend class DaeBuilderInternal;
70 
71  private:
73  Variable(casadi_int index, casadi_int numel, const std::string& name, const MX& v);
74 
75  public:
77  casadi_int index;
78 
80  casadi_int numel;
81 
83  std::vector<casadi_int> dimension;
84 
87  std::string name;
88  unsigned int value_reference;
89  std::string description;
94 
97  // std::string declared_type;
98  std::string unit;
99  std::string display_unit;
101  // std::string quantity;
102  // bool relative_quantity;
103  // bool unbounded;
104  double min;
105  double max;
106  double nominal;
107  std::vector<double> start;
108  casadi_int der_of; // 'derivative' in FMI specification
109  // bool reinit;
111 
112  // corresponding residual variable
113  casadi_int alg;
114 
115  // corresponding derivative variable
116  casadi_int der;
117 
119  std::vector<double> value;
120 
122  std::string stringvalue;
123 
126 
128  mutable std::vector<casadi_int> dependencies;
129 
131  mutable std::vector<DependenciesKind> dependenciesKind;
132 
134  MX v;
135 
138 
140  double attribute(Attribute a) const;
141 
143  void set_attribute(Attribute a, double val);
144 
146  std::string string_attribute(Attribute a) const;
147 
149  void set_string_attribute(Attribute a, const std::string& val);
150 
151  // Default initial attribute, per specification
152  static Initial default_initial(Causality causality, Variability variability);
153 
154  // Export as XML
155  XmlNode export_xml(const DaeBuilderInternal& self) const;
156 
157  // Is the variable real?
158  bool is_real() const {return type == Type::FLOAT32 || type == Type::FLOAT64;}
159 
160  // Does the variable need a start attribute?
161  bool has_start() const;
162 };
163 
166 class CASADI_EXPORT DaeBuilderInternal : public SharedObjectInternal {
167  friend class DaeBuilder;
168  friend class Fmu2;
169  friend class FmuFunction;
170 
171  public:
172 
174  explicit DaeBuilderInternal(const std::string& name, const std::string& path, const Dict& opts);
175 
177  ~DaeBuilderInternal() override;
178 
180  std::string class_name() const override {return "DaeBuilderInternal";}
181 
183  void sanity_check() const;
184 
189 
191  void eliminate_w();
192 
194  void lift(bool lift_shared, bool lift_calls);
195 
197  void eliminate_quad();
198 
200  void sort_d();
201 
203  void sort_w();
204 
206  void sort_z(const std::vector<std::string>& z_order);
207 
209  std::vector<size_t>& ind_in(const std::string& v);
210 
212  const std::vector<size_t>& ind_in(const std::string& v) const;
213 
215  void clear_all(const std::string& v);
216 
218  void set_all(const std::string& v, const std::vector<std::string>& name);
219 
221  void prune(bool prune_p, bool prune_u);
222 
224  void tearing_variables(std::vector<std::string>* res, std::vector<std::string>* iv,
225  std::vector<std::string>* iv_on_hold) const;
226 
228  void tear();
230 
235  void load_fmi_description(const std::string& filename);
236 
238  static std::string iso_8601_time();
239 
240  // Generate a random 32 digit hexadecimal number
241  static std::string generate_guid();
242 
244  std::vector<std::string> export_fmu(const Dict& opts) const;
245 
247  std::string generate_wrapper(const std::string& guid, const CodeGenerator& gen) const;
248 
250  std::string generate_build_description(const std::vector<std::string>& cfiles) const;
251 
253  std::string generate_model_description(const std::string& guid) const;
254 
256  XmlNode generate_model_variables() const;
257 
259  XmlNode generate_model_structure() const;
260 
262  void update_dependencies() const;
263 
266  static std::string generate(const std::vector<size_t>& v);
267  static std::string generate(const std::vector<double>& v);
269 
270  // Input convension in codegen
271  enum DaeBuilderInternalIn {
272  DAE_BUILDER_T,
273  DAE_BUILDER_C,
274  DAE_BUILDER_P,
275  DAE_BUILDER_D,
276  DAE_BUILDER_W,
277  DAE_BUILDER_U,
278  DAE_BUILDER_X,
279  DAE_BUILDER_Z,
280  DAE_BUILDER_Q,
281  DAE_BUILDER_Y,
282  DAE_BUILDER_NUM_IN
283  };
284 
285  // Output convension in codegen
286  enum DaeBuilderInternalOut {
287  DAE_BUILDER_ODE,
288  DAE_BUILDER_ALG,
289  DAE_BUILDER_QUAD,
290  DAE_BUILDER_DDEF,
291  DAE_BUILDER_WDEF,
292  DAE_BUILDER_YDEF,
293  DAE_BUILDER_NUM_OUT
294  };
295 
296  // Get input expression, given enum
297  std::vector<MX> input(DaeBuilderInternalIn ind) const;
298 
299  // Get output expression, given enum
300  std::vector<MX> output(DaeBuilderInternalOut ind) const;
301 
302  // Get input expression, given enum
303  std::vector<MX> input(const std::vector<DaeBuilderInternalIn>& ind) const;
304 
305  // Get output expression, given enum
306  std::vector<MX> output(const std::vector<DaeBuilderInternalOut>& ind) const;
307 
309  void add_lc(const std::string& name, const std::vector<std::string>& f_out);
310 
312  Function create(const std::string& fname,
313  const std::vector<std::string>& name_in,
314  const std::vector<std::string>& name_out,
315  const Dict& opts, bool sx, bool lifted_calls) const;
316 
318  Function fmu_fun(const std::string& fname,
319  const std::vector<std::string>& name_in,
320  const std::vector<std::string>& name_out,
321  const Dict& opts) const;
322 
324  Function dependent_fun(const std::string& fname,
325  const std::vector<std::string>& s_in,
326  const std::vector<std::string>& s_out) const;
327 
329  Function gather_eq() const;
330 
332  const MX& var(const std::string& name) const;
333 
335  MX der(const std::string& name) const;
336 
338  MX der(const MX& var) const;
339 
341  std::string type_name() const {return "DaeBuilderInternal";}
342 
344  void disp(std::ostream& stream, bool more) const override;
345 
347  std::string get_str(bool more=false) const {
348  std::stringstream ss;
349  disp(ss, more);
350  return ss.str();
351  }
352 
354  Variable& new_variable(const std::string& name, casadi_int numel = 1, const MX& v = MX());
355 
357  bool has_variable(const std::string& name) const;
358 
360  std::vector<std::string> all_variables() const;
361 
363  size_t n_variables() const {return variables_.size();}
364 
366  size_t n_mem() const;
367 
369  std::vector<double> start_all() const;
370 
373  Variable& variable(size_t ind) {return *variables_.at(ind);}
374  const Variable& variable(size_t ind) const {return *variables_.at(ind);}
376 
379  Variable& variable(const std::string& name) {return variable(find(name));}
380  const Variable& variable(const std::string& name) const {return variable(find(name));}
382 
384  const MX& var(size_t ind) const;
385 
387  std::vector<MX> var(const std::vector<size_t>& ind) const;
388 
390  size_t find(const std::string& name) const;
391 
393  std::vector<size_t> find(const std::vector<std::string>& name) const;
394 
396  const Function& oracle(bool sx = false, bool elim_w = false, bool lifted_calls = false) const;
397 
399  Sparsity jac_sparsity(const std::vector<size_t>& oind, const std::vector<size_t>& iind) const;
400 
402  Sparsity hess_sparsity(const std::vector<size_t>& oind, const std::vector<size_t>& iind) const;
403 
404  // Internal methods
405 protected:
406 
408  static std::string qualified_name(const XmlNode& nn);
409 
410  // User-set options
411  bool debug_;
412  double fmutol_;
413 
414  // FMI attributes
415  std::string fmi_version_;
416  std::string model_name_;
417  std::string guid_;
418  std::string description_;
419  std::string author_;
420  std::string copyright_;
421  std::string license_;
422  std::string generation_tool_;
423  std::string generation_date_and_time_;
424  std::string variable_naming_convention_;
425  casadi_int number_of_event_indicators_;
426 
427  // Model Exchange
428  std::string model_identifier_;
429  bool provides_directional_derivative_;
430  std::vector<std::string> source_files_;
431 
433  std::string name_;
434 
435  // Path to FMU, if any
436  std::string path_;
437 
438  // Symbolic representation of the model equations?
439  bool symbolic_;
440 
442  std::vector<Variable*> variables_;
443 
444  // Model structure
445  std::vector<size_t> outputs_, derivatives_, initial_unknowns_;
446 
448  std::unordered_map<std::string, size_t> varind_;
449 
451  std::vector<size_t> t_, p_, u_, x_, z_, q_, c_, d_, w_, y_;
452 
455  std::vector<MX> aux_;
456  std::vector<MX> init_lhs_, init_rhs_;
457  std::vector<MX> when_cond_, when_lhs_, when_rhs_;
459 
463  std::vector<MX> cdef() const;
464 
468  std::vector<MX> ddef() const;
469 
473  std::vector<MX> wdef() const;
474 
478  std::vector<MX> ydef() const;
479 
483  std::vector<MX> ode() const;
484 
488  std::vector<MX> alg() const;
489 
493  std::vector<MX> quad() const;
494 
497  MX add_t(const std::string& name);
498  MX add_p(const std::string& name);
499  MX add_u(const std::string& name);
500  MX add_x(const std::string& name);
501  MX add_z(const std::string& name);
502  MX add_q(const std::string& name);
503  MX add_c(const std::string& name, const MX& new_cdef);
504  MX add_d(const std::string& name, const MX& new_ddef);
505  MX add_w(const std::string& name, const MX& new_wdef);
506  MX add_y(const std::string& name, const MX& new_ydef);
507  void set_ode(const std::string& name, const MX& ode_rhs);
508  void set_alg(const std::string& name, const MX& alg_rhs);
510 
512  Function::AuxOut lc_;
513 
517  std::vector<Function> fun_;
518 
522  mutable Function oracle_[2][2][2];
523 
525  mutable bool clear_cache_;
526 
528  MX read_expr(const XmlNode& node);
529 
531  Variable& read_variable(const XmlNode& node);
532 
533  // Read ModelExchange
534  void import_model_exchange(const XmlNode& n);
535 
536  // Read ModelVariables
537  void import_model_variables(const XmlNode& modvars);
538 
539  // Read ModelStructure
540  void import_model_structure(const XmlNode& n);
541 
543  void clear_cache() const;
544 
546  Function add_fun(const std::string& name,
547  const std::vector<std::string>& arg,
548  const std::vector<std::string>& res, const Dict& opts=Dict());
549 
551  Function add_fun(const Function& f);
552 
554  bool has_fun(const std::string& name) const;
555 
557  Function fun(const std::string& name) const;
558 
559  // Reset value attributes
560  void reset();
561 
564  double attribute(Attribute a, const std::string& name) const;
565  std::vector<double> attribute(Attribute a, const std::vector<std::string>& name) const;
567 
570  void set_attribute(Attribute a, const std::string& name, double val);
571  void set_attribute(Attribute a, const std::vector<std::string>& name,
572  const std::vector<double>& val);
574 
577  std::string string_attribute(Attribute a, const std::string& name) const;
578  std::vector<std::string> string_attribute(Attribute a,
579  const std::vector<std::string>& name) const;
581 
584  void set_string_attribute(Attribute a, const std::string& name, const std::string& val);
585  void set_string_attribute(Attribute a, const std::vector<std::string>& name,
586  const std::vector<std::string>& val);
588 
589 
591  struct CallIO {
592  // Function instances
593  Function f, adj1_f, J, H;
594  // Index in v and vdef
595  std::vector<size_t> v, vdef;
596  // Nondifferentiated inputs
597  std::vector<MX> arg;
598  // Nondifferentiated inputs
599  std::vector<MX> res;
600  // Jacobian outputs
601  std::vector<MX> jac_res;
602  // Adjoint seeds
603  std::vector<MX> adj1_arg;
604  // Adjoint sensitivities
605  std::vector<MX> adj1_res;
606  // Hessian outputs
607  std::vector<MX> hess_res;
608  // Calculate Jacobian blocks
609  void calc_jac();
610  // Calculate gradient of Lagrangian
611  void calc_grad();
612  // Calculate Hessian of Lagrangian
613  void calc_hess();
614  // Access a specific Jacobian block
615  const MX& jac(casadi_int oind, casadi_int iind) const;
616  // Access a specific Hessian block
617  const MX& hess(casadi_int iind1, casadi_int iind2) const;
618  };
619 
621  MX jac_vdef_v_from_calls(std::map<MXNode*, CallIO>& call_nodes,
622  const std::vector<casadi_int>& h_offsets) const;
623 
625  MX hess_v_v_from_calls(std::map<MXNode*, CallIO>& call_nodes,
626  const std::vector<casadi_int>& h_offsets) const;
627 
628  // Sort dependent variables/parameters
629  static void sort_dependent(std::vector<MX>& v, std::vector<MX>& vdef);
630 };
631 
634 template<> struct enum_traits<DaeBuilderInternal::DaeBuilderInternalIn> {
635  static const size_t n_enum = DaeBuilderInternal::DAE_BUILDER_NUM_IN;
636 };
637 template<> struct enum_traits<DaeBuilderInternal::DaeBuilderInternalOut> {
638  static const size_t n_enum = DaeBuilderInternal::DAE_BUILDER_NUM_OUT;
639 };
641 
644 CASADI_EXPORT Type from_fmi2(TypeFmi2 v);
645 CASADI_EXPORT TypeFmi2 to_fmi2(Type v);
647 
650 CASADI_EXPORT std::string to_string(TypeFmi2 v);
651 CASADI_EXPORT std::string to_string(Type v);
652 CASADI_EXPORT std::string to_string(Causality v);
653 CASADI_EXPORT std::string to_string(Variability v);
654 CASADI_EXPORT std::string to_string(Initial v);
655 CASADI_EXPORT std::string to_string(Attribute v);
656 CASADI_EXPORT std::string to_string(DependenciesKind v);
657 CASADI_EXPORT std::string to_string(DaeBuilderInternal::DaeBuilderInternalIn v);
658 CASADI_EXPORT std::string to_string(DaeBuilderInternal::DaeBuilderInternalOut v);
660 
662 
663 } // namespace casadi
664 
665 #endif // CASADI_DAE_BUILDER_INTERNAL_HPP
A symbolic representation of a differential-algebraic equations model.
Definition: dae_builder.hpp:70
std::map< std::string, std::vector< std::string > > AuxOut
Definition: function.hpp:395
MX - Matrix expression.
Definition: mx.hpp:84
The casadi namespace.
Variability
Variability: FMI 2.0 specification, section 2.2.7 or FMI 3.0 specification, section 2....
GenericType::Dict Dict
C++ equivalent of Python's dict or MATLAB's struct.
Initial
Initial: FMI 2.0 specification, section 2.2.7 or FMI 3.0 specification, section 2....
Causality
Causality: FMI 2.0 specification, section 2.2.7 or FMI 3.0 specification, section 2....
Type
Variable type (FMI 3)
TypeFmi2
Variable type (FMI 2)
Holds expressions and meta-data corresponding to a physical quantity evolving in time.
bool dependency
Do other expressions depend on this variable.
void set_attribute(Attribute a, double val)
Set by attribute name.
std::vector< double > value
Numerical value (also for booleans, integers, enums)
void set_string_attribute(Attribute a, const std::string &val)
Set by attribute name (string-valued)
bool has_start() const
static Initial default_initial(Causality causality, Variability variability)
MX beq
Binding equation.
std::vector< double > start
casadi_int index
Location in variable vector.
std::string stringvalue
String value (if string-valued)
casadi_int numel
Number of elements - product of all dimensions.
unsigned int value_reference
MX v
Variable expression.
XmlNode export_xml(const DaeBuilderInternal &self) const
std::vector< casadi_int > dependencies
Dependencies.
std::vector< DependenciesKind > dependenciesKind
Dependencies.
double attribute(Attribute a) const
Get by attribute name.
std::vector< casadi_int > dimension
Dimensions.
std::string string_attribute(Attribute a) const
Get by attribute name (string-valued)