integrator_impl.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_INTEGRATOR_IMPL_HPP
27 #define CASADI_INTEGRATOR_IMPL_HPP
28 
29 #include "integrator.hpp"
30 #include "oracle_function.hpp"
31 #include "plugin_interface.hpp"
32 #include "casadi_enum.hpp"
33 
35 
36 namespace casadi {
37 
41 struct CASADI_EXPORT IntegratorMemory : public OracleMemory {
42  // Current control interval
43  casadi_int k;
44  // Current time
45  double t;
46  // Next time to be visited by the integrator
47  double t_next;
48  // Next stop time due to step change in input, continuous
49  double t_stop;
50 };
51 
53 struct CASADI_EXPORT SpForwardMem {
54  const bvec_t** arg;
55  bvec_t** res;
56  casadi_int* iw;
57  bvec_t* w;
58 };
59 
61 struct CASADI_EXPORT SpReverseMem {
62  bvec_t** arg;
63  bvec_t** res;
64  casadi_int* iw;
65  bvec_t* w;
66 };
67 
75 class CASADI_EXPORT
76 Integrator : public OracleFunction, public PluginInterface<Integrator> {
77  public:
81  Integrator(const std::string& name, const Function& oracle,
82  double t0, const std::vector<double>& tout);
83 
87  ~Integrator() override=0;
88 
90 
93  size_t get_n_in() override { return INTEGRATOR_NUM_IN;}
94  size_t get_n_out() override { return INTEGRATOR_NUM_OUT;}
96 
98 
101  Sparsity get_sparsity_in(casadi_int i) override;
102  Sparsity get_sparsity_out(casadi_int i) override;
104 
106 
109  std::string get_name_in(casadi_int i) override { return integrator_in(i);}
110  std::string get_name_out(casadi_int i) override { return integrator_out(i);}
112 
116  int init_mem(void* mem) const override;
117 
119 
122  static const Options options_;
123  const Options& get_options() const override { return options_;}
125 
129  void init(const Dict& opts) override;
130 
132  virtual Function create_advanced(const Dict& opts);
133 
134  virtual MX algebraic_state_init(const MX& x0, const MX& z0) const { return z0; }
135  virtual MX algebraic_state_output(const MX& Z) const { return Z; }
136 
140  virtual void reset(IntegratorMemory* mem,
141  const double* u, const double* x, const double* z, const double* p) const = 0;
142 
146  casadi_int next_stop(casadi_int k, const double* u) const;
147 
151  virtual void advance(IntegratorMemory* mem,
152  const double* u, double* x, double* z, double* q) const = 0;
153 
157  virtual void resetB(IntegratorMemory* mem) const = 0;
158 
162  casadi_int next_stopB(casadi_int k, const double* u) const;
163 
167  virtual void impulseB(IntegratorMemory* mem,
168  const double* rx, const double* rz, const double* rp) const = 0;
169 
173  virtual void retreat(IntegratorMemory* mem, const double* u,
174  double* rx, double* rq, double* uq) const = 0;
175 
179  int eval(const double** arg, double** res, casadi_int* iw, double* w, void* mem) const override;
180 
184  virtual void print_stats(IntegratorMemory* mem) const {}
185 
187  int fdae_sp_forward(SpForwardMem* m, const bvec_t* x,
188  const bvec_t* p, const bvec_t* u, bvec_t* ode, bvec_t* alg) const;
189 
191  int fquad_sp_forward(SpForwardMem* m, const bvec_t* x, const bvec_t* z,
192  const bvec_t* p, const bvec_t* u, bvec_t* quad) const;
193 
195  int bdae_sp_forward(SpForwardMem* m, const bvec_t* x, const bvec_t* z,
196  const bvec_t* p, const bvec_t* u, const bvec_t* rx, const bvec_t* rp,
197  bvec_t* adj_x, bvec_t* adj_z) const;
198 
200  int bquad_sp_forward(SpForwardMem* m, const bvec_t* x, const bvec_t* z,
201  const bvec_t* p, const bvec_t* u, const bvec_t* rx, const bvec_t* rz, const bvec_t* rp,
202  bvec_t* adj_p, bvec_t* adj_u) const;
203 
207  int sp_forward(const bvec_t** arg, bvec_t** res,
208  casadi_int* iw, bvec_t* w, void* mem) const override;
209 
211  int fdae_sp_reverse(SpReverseMem* m, bvec_t* x,
212  bvec_t* p, bvec_t* u, bvec_t* ode, bvec_t* alg) const;
213 
215  int fquad_sp_reverse(SpReverseMem* m, bvec_t* x, bvec_t* z,
216  bvec_t* p, bvec_t* u, bvec_t* quad) const;
217 
219  int bdae_sp_reverse(SpReverseMem* m, bvec_t* x, bvec_t* z,
220  bvec_t* p, bvec_t* u, bvec_t* rx, bvec_t* rp,
221  bvec_t* adj_x, bvec_t* adj_z) const;
222 
224  int bquad_sp_reverse(SpReverseMem* m, bvec_t* x, bvec_t* z,
225  bvec_t* p, bvec_t* u, bvec_t* rx, bvec_t* rz, bvec_t* rp,
226  bvec_t* adj_p, bvec_t* adj_u) const;
227 
231  int sp_reverse(bvec_t** arg, bvec_t** res, casadi_int* iw, bvec_t* w, void* mem) const override;
232 
235  bool has_spfwd() const override { return true;}
236  bool has_sprev() const override { return true;}
238 
240 
243  Function get_forward(casadi_int nfwd, const std::string& name,
244  const std::vector<std::string>& inames,
245  const std::vector<std::string>& onames,
246  const Dict& opts) const override;
247  bool has_forward(casadi_int nfwd) const override { return true;}
249 
251 
254  Function get_reverse(casadi_int nadj, const std::string& name,
255  const std::vector<std::string>& inames,
256  const std::vector<std::string>& onames,
257  const Dict& opts) const override;
258  bool has_reverse(casadi_int nadj) const override { return true;}
260 
264  virtual Dict getDerivativeOptions(bool fwd) const;
265 
267 
270  template<typename MatType> Function get_forward_dae(const std::string& name) const;
271  Function augmented_dae() const;
273 
275  static bool all_zero(const double* v, casadi_int n);
276 
278  Sparsity sp_jac_aug(const Sparsity& J, const Sparsity& J1) const;
279 
281  Sparsity sp_jac_dae();
282 
284  Sparsity sp_jac_rdae();
285 
287  Sparsity sp_jac_dae_, sp_jac_rdae_;
288 
290  inline casadi_int nt() const { return tout_.size();}
291 
293 
296  enum DaeOut { DAE_ODE, DAE_ALG, DAE_NUM_OUT};
297  static std::vector<std::string> dae_out() { return {"ode", "alg"}; }
298  enum QuadOut { QUAD_QUAD, QUAD_NUM_OUT};
299  static std::vector<std::string> quad_out() { return {"quad"}; }
300  enum BDynIn { BDYN_T, BDYN_X, BDYN_Z, BDYN_P, BDYN_U,
301  BDYN_OUT_ODE, BDYN_OUT_ALG, BDYN_OUT_QUAD,
302  BDYN_ADJ_ODE, BDYN_ADJ_ALG, BDYN_ADJ_QUAD, BDYN_NUM_IN};
303  static std::string bdyn_in(casadi_int i);
304  static std::vector<std::string> bdyn_in();
305  enum BDynOut { BDYN_ADJ_T, BDYN_ADJ_X, BDYN_ADJ_Z, BDYN_ADJ_P, BDYN_ADJ_U, BDYN_NUM_OUT};
306  static std::string bdyn_out(casadi_int i);
307  static std::vector<std::string> bdyn_out();
308  enum DAEBOut { BDAE_ADJ_X, BDAE_ADJ_Z, BDAE_NUM_OUT};
309  static std::vector<std::string> bdae_out() { return {"adj_x", "adj_z"}; }
310  enum QuadBOut { BQUAD_ADJ_P, BQUAD_ADJ_U, BQUAD_NUM_OUT};
311  static std::vector<std::string> bquad_out() { return {"adj_p", "adj_u"}; }
313 
315  double t0_;
316 
318  std::vector<double> tout_;
319 
321  casadi_int nfwd_, nadj_;
322 
324  Function rdae_;
325 
327  casadi_int nx_, nz_, nq_, nx1_, nz1_, nq1_;
328 
330  casadi_int nrx_, nrz_, nrq_, nuq_, nrx1_, nrz1_, nrq1_, nuq1_;
331 
333  casadi_int np_, nrp_, np1_, nrp1_;
334 
336  casadi_int nu_, nu1_;
337 
338  // Nominal values for states
339  std::vector<double> nom_x_, nom_z_;
340 
342  Dict augmented_options_;
343 
345  Dict opts_;
346 
348  bool print_stats_;
349 
350  // Creator function for internal class
351  typedef Integrator* (*Creator)(const std::string& name, const Function& oracle,
352  double t0, const std::vector<double>& tout);
353 
354  // No static functions exposed
355  struct Exposed{ };
356 
358  static std::map<std::string, Plugin> solvers_;
359 
361  static const std::string infix_;
362 
364  template<typename XType>
365  static Function map2oracle(const std::string& name, const std::map<std::string, XType>& d);
366 
370  void serialize_body(SerializingStream &s) const override;
374  void serialize_type(SerializingStream &s) const override;
375 
379  static ProtoFunction* deserialize(DeserializingStream& s);
380 
384  std::string serialize_base_function() const override { return "Integrator"; }
385 
387  static bool grid_in(casadi_int i);
388 
390  static bool grid_out(casadi_int i);
391 
393  static casadi_int adjmap_out(casadi_int i);
394 
395  protected:
399  explicit Integrator(DeserializingStream& s);
400 };
401 
403 enum StepIn {
405  STEP_T,
407  STEP_H,
409  STEP_X0,
411  STEP_V0,
413  STEP_P,
415  STEP_U,
417  STEP_NUM_IN
418 };
419 
421 enum StepOut {
423  STEP_XF,
425  STEP_VF,
427  STEP_QF,
429  STEP_NUM_OUT
430 };
431 
433 enum BStepIn {
434  BSTEP_T,
435  BSTEP_H,
436  BSTEP_X0,
437  BSTEP_V0,
438  BSTEP_P,
439  BSTEP_U,
440  BSTEP_OUT_XF,
441  BSTEP_OUT_VF,
442  BSTEP_OUT_QF,
443  BSTEP_ADJ_XF,
444  BSTEP_ADJ_VF,
445  BSTEP_ADJ_QF,
446  BSTEP_NUM_IN
447 };
448 
450 enum BStepOut {
451  BSTEP_ADJ_T,
452  BSTEP_ADJ_H,
453  BSTEP_ADJ_X0,
454  BSTEP_ADJ_V0,
455  BSTEP_ADJ_P,
456  BSTEP_ADJ_U,
457  BSTEP_NUM_OUT
458 };
459 
460 struct CASADI_EXPORT FixedStepMemory : public IntegratorMemory {
461  // Work vectors, allocated in base class
462  double *x, *z, *rx, *rz, *rq, *x_prev, *rx_prev;
463 
465  double *v, *p, *u, *q, *v_prev, *q_prev;
466 
468  double *rv, *rp, *uq, *rq_prev, *uq_prev;
469 
471  double *x_tape, *v_tape;
472 };
473 
474 class CASADI_EXPORT FixedStepIntegrator : public Integrator {
475  public:
476 
478  explicit FixedStepIntegrator(const std::string& name, const Function& dae,
479  double t0, const std::vector<double>& tout);
480 
482  ~FixedStepIntegrator() override;
483 
485 
488  static const Options options_;
489  const Options& get_options() const override { return options_;}
491 
493  void init(const Dict& opts) override;
494 
498  void set_work(void* mem, const double**& arg, double**& res,
499  casadi_int*& iw, double*& w) const override;
500 
502  Function create_advanced(const Dict& opts) override;
503 
507  void* alloc_mem() const override { return new FixedStepMemory();}
508 
512  int init_mem(void* mem) const override;
513 
517  void free_mem(void *mem) const override { delete static_cast<FixedStepMemory*>(mem);}
518 
520  virtual void setup_step() = 0;
521 
525  void reset(IntegratorMemory* mem,
526  const double* u, const double* x, const double* z, const double* p) const override;
527 
531  void advance(IntegratorMemory* mem,
532  const double* u, double* x, double* z, double* q) const override;
533 
535  void resetB(IntegratorMemory* mem) const override;
536 
538  void impulseB(IntegratorMemory* mem,
539  const double* rx, const double* rz, const double* rp) const override;
540 
544  void retreat(IntegratorMemory* mem, const double* u,
545  double* rx, double* rq, double* uq) const override;
546 
548  void stepF(FixedStepMemory* m, double t, double h,
549  const double* x0, const double* v0, double* xf, double* vf, double* qf) const;
550 
552  void stepB(FixedStepMemory* m, double t, double h,
553  const double* x0, const double* xf, const double* vf,
554  const double* rx0, const double* rv0,
555  double* rxf, double* rqf, double* uqf) const;
556 
557  // Target number of finite elements
558  casadi_int nk_target_;
559 
560  // Number of steps per control interval
561  std::vector<casadi_int> disc_;
562 
564  casadi_int nv_, nv1_, nrv_, nrv1_;
565 
569  void serialize_body(SerializingStream &s) const override;
570 
571 protected:
575  explicit FixedStepIntegrator(DeserializingStream& s);
576 };
577 
578 class CASADI_EXPORT ImplicitFixedStepIntegrator : public FixedStepIntegrator {
579  public:
580 
582  explicit ImplicitFixedStepIntegrator(const std::string& name, const Function& dae,
583  double t0, const std::vector<double>& tout);
584 
586  ~ImplicitFixedStepIntegrator() override;
587 
589 
592  static const Options options_;
593  const Options& get_options() const override { return options_;}
595 
597  void init(const Dict& opts) override;
598 
602  void serialize_body(SerializingStream &s) const override;
603 
604 protected:
608  explicit ImplicitFixedStepIntegrator(DeserializingStream& s);
609 };
610 
611 } // namespace casadi
613 
614 #endif // CASADI_INTEGRATOR_IMPL_HPP
CASADI_EXPORT std::vector< std::string > integrator_in()
Get input scheme of integrators.
CASADI_EXPORT std::vector< std::string > integrator_out()
Get integrator output scheme of integrators.
The casadi namespace.
GenericType::Dict Dict
C++ equivalent of Python's dict or MATLAB's struct.