runtime_integrator.hpp
1 /*
2  * This file is part of CasADi.
3  *
4  * CasADi -- A symbolic framework for dynamic optimization.
5  * Copyright (C) 2010-2026 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_RUNTIME_INTEGRATOR_HPP
27 #define CASADI_RUNTIME_INTEGRATOR_HPP
28 
29 #include "integrator_impl.hpp"
30 
32 
33 namespace casadi {
34 
35 struct CASADI_EXPORT RuntimeIntegratorMemory : public IntegratorMemory {
36  // Reverse communication data, and of the nominal integration whose steps are replayed
38  // Tape of unbounded size, if the work vector has none
39  std::vector<double> tape;
40 };
41 
49 class CASADI_EXPORT RuntimeIntegrator : public Integrator {
50  public:
51 
53  RuntimeIntegrator(const std::string& name, const Function& dae, double t0,
54  const std::vector<double>& tout);
55 
57  ~RuntimeIntegrator() override;
58 
60 
63  static const Options options_;
64  const Options& get_options() const override { return options_;}
66 
68  void init(const Dict& opts) override;
69 
73  void set_work(void* mem, const double**& arg, double**& res,
74  casadi_int*& iw, double*& w) const override;
75 
79  int init_mem(void* mem) const override;
80 
82  void reset(IntegratorMemory* mem, bool first_call) const override;
83 
85  int advance_noevent(IntegratorMemory* mem) const override;
86 
88  bool has_reverse(casadi_int nadj) const override { return true;}
89 
91  void resetB(IntegratorMemory* mem) const override;
92 
94  void impulseB(IntegratorMemory* mem,
95  const double* adj_x, const double* adj_z, const double* adj_q) const override;
96 
99  Sparsity get_sparsity_in(casadi_int i) override;
100  Sparsity get_sparsity_out(casadi_int i) override;
102 
104  int eval(const double** arg, double** res, casadi_int* iw, double* w,
105  void* mem) const override;
106 
109  int sp_forward(const bvec_t** arg, bvec_t** res,
110  casadi_int* iw, bvec_t* w, void* mem) const override;
111  int sp_reverse(bvec_t** arg, bvec_t** res, casadi_int* iw, bvec_t* w,
112  void* mem) const override;
114 
116  void retreat(IntegratorMemory* mem, const double* u,
117  double* adj_x, double* adj_p, double* adj_u) const override;
118 
120  Dict get_stats(void* mem) const override;
121 
123  void print_stats(IntegratorMemory* mem) const override;
124 
126 
129  bool has_codegen() const override;
130  void codegen_declarations(CodeGenerator& g) const override;
131  void codegen_body(CodeGenerator& g) const override;
133 
137  void serialize_body(SerializingStream &s) const override;
138 
139  protected:
140 
145 
147  virtual bool needs_jacobian() const = 0;
148 
150  virtual int kernel(RuntimeIntegratorMemory* m) const = 0;
151 
153  virtual void codegen_method(CodeGenerator& g) const = 0;
154 
156  const RuntimeIntegrator* root() const;
157 
159  void set_ivp_prob();
160 
162  Function jump_function() const;
163 
165  void set_nominal_prob();
166 
168  casadi_int ngroup() const { return group_start_.size() - 1;}
169 
171  void alloc_ivp_work();
172 
174  void run(RuntimeIntegratorMemory* m) const;
175 
177  casadi_int tape_capacity() const;
178 
179  // Method coefficients: stage arguments, nodes, weights, dense output weights, weights of the
180  // error estimate (empty: fixed steps only) and its order
181  std::vector<double> a_, alpha_, m_, m_dense_, m_err_;
182  casadi_int n_dense_, order_err_;
183 
184  // First output interval of each control group, followed by the number of output times
185  std::vector<casadi_int> group_start_;
186 
187  // Leading entries of x, z, q subject to error control
188  casadi_int nx_err_, nz_err_, nq_err_;
189 
190  // Options
191  double step_size_, abstol_, reltol_, step0_, max_step_size_, min_step_size_;
192  casadi_int max_num_steps_, max_tape_steps_;
194 
195  // Sparsity of the Jacobian blocks, see casadi_ivp_jac_t (empty: no linearization)
196  std::vector<Sparsity> sp_jac_;
197 
198  // Shared problem structure
200 
201  // Steps replayed from a nominal integration with the functions of the root integrator
202  bool replay_;
204 
205  private:
206  // Source buffers of function arguments and results, see slot_ptr and slot_expr
207  enum Src {SRC_T, SRC_Y, SRC_P, SRC_U, SRC_RES, SRC_W, SRC_JAC, SRC_JAC_FWD, SRC_JAC_ADJ,
208  SRC_JAC_ADJ_FWD, SRC_VJP_X, SRC_VJP_Z, SRC_VJP_P, SRC_VJP_U, SRC_EV_ONE, SRC_EV_W, SRC_YDOT,
209  SRC_EDOT};
210 
211  // Argument or result i of a function call: buffer src at offset off
212  struct Slot {
213  casadi_int i;
214  Src src;
215  casadi_int off;
216  };
217 
218  // Function call of a task: arguments and results not listed are null
219  struct TaskCall {
220  std::string fname;
221  casadi_int n_in, n_out;
222  std::vector<Slot> arg, res;
223  };
224 
225  // For each task of the kernel, the function calls (function names with a suffix)
226  std::vector<std::vector<TaskCall>> task_calls(const std::string& suffix) const;
227 
228  // Carry out a task of data d with a task table
229  int eval_task(RuntimeIntegratorMemory* m, casadi_ivp_data<double>* d,
230  const std::vector<std::vector<TaskCall>>& calls) const;
231 
232  // Buffer of a slot in the virtual machine, and in generated code
233  double* slot_ptr(RuntimeIntegratorMemory* m, casadi_ivp_data<double>* d, const Slot& e) const;
234  static std::string slot_expr(const std::string& d, const Slot& e);
235 
236  // Reverse communication: evaluate the function requested by the kernel
237  int task(RuntimeIntegratorMemory* m) const;
238 
239  // Generate code for the tasks of data variable d, as eval_task
240  void codegen_task(CodeGenerator& g, const std::string& d,
241  const std::vector<std::vector<TaskCall>>& calls, bool in_event = false) const;
242 
243  // Generate code for the task loop of the kernel
244  void codegen_loop(CodeGenerator& g) const;
245 
246  // Generate code for the shared problem structure in variable p
247  void codegen_ivp_prob(CodeGenerator& g, const std::string& p, casadi_int tape_size) const;
248 
249  // Function calls of the tasks, and of the tasks of the nominal integration
250  std::vector<std::vector<TaskCall>> calls_, calls_nom_;
251 };
252 
253 } // namespace casadi
255 
256 #endif // CASADI_RUNTIME_INTEGRATOR_HPP
Helper class for C code generation.
Helper class for Serialization.
Function object.
Definition: function.hpp:126
Internal storage for integrator related data.
Base class of one-step integrators driven by a reverse communication kernel.
std::vector< Sparsity > sp_jac_
bool has_reverse(casadi_int nadj) const override
Adjoint sensitivities, also with events.
std::vector< casadi_int > group_start_
casadi_ivp_prob< double > p_nom_
virtual void codegen_method(CodeGenerator &g) const =0
Generate code for the problem and data of the method, variables pe and e.
const Options & get_options() const override
Options.
casadi_ivp_prob< double > p_
casadi_int ngroup() const
Number of control groups, columns of the controls.
virtual int kernel(RuntimeIntegratorMemory *m) const =0
Call the kernel of the method: returns 1 while a task is requested.
virtual bool needs_jacobian() const =0
Does the method linearize (tasks EVAL_JAC, EVAL_JAC_ADJ)?
static const Options options_
Options.
Helper class for Serialization.
General sparsity class.
Definition: sparsity.hpp:200
The casadi namespace.
Definition: archiver.cpp:28
unsigned long long bvec_t
GenericType::Dict Dict
C++ equivalent of Python's dict or MATLAB's struct.
Options metadata for a class.
Definition: options.hpp:40