cvodes_interface.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_CVODES_INTERFACE_HPP
27 #define CASADI_CVODES_INTERFACE_HPP
28 
29 #include <casadi/interfaces/sundials/casadi_integrator_cvodes_export.h>
30 #include "sundials_interface.hpp"
31 #include <cvodes/cvodes.h> /* prototypes for CVode fcts. and consts. */
32 #include <cvodes/cvodes_dense.h>
33 #include <cvodes/cvodes_band.h>
34 #include <cvodes/cvodes_spgmr.h>
35 #include <cvodes/cvodes_spbcgs.h>
36 #include <cvodes/cvodes_sptfqmr.h>
37 #include <cvodes/cvodes_impl.h> /* Needed for the provided linear solver */
38 #include <ctime>
39 
55 namespace casadi {
56 
57 // Forward declaration
58 class CvodesInterface;
59 
60 // CvodesMemory
61 struct CvodesMemory : public SundialsMemory {
63  const CvodesInterface& self;
64 
65  // CVodes memory block
66  void* mem;
67 
68  // Ids of backward problem
69  int whichB;
70 
71  // Remember the gamma and gammaB from last factorization
72  double gamma, gammaB;
73 
75  CvodesMemory(const CvodesInterface& s);
76 
78  ~CvodesMemory();
79 };
80 
87 class CvodesInterface : public SundialsInterface {
88  public:
90  CvodesInterface(const std::string& name, const Function& dae, double t0,
91  const std::vector<double>& tout);
92 
94  static Integrator* creator(const std::string& name, const Function& dae,
95  double t0, const std::vector<double>& tout) {
96  return new CvodesInterface(name, dae, t0, tout);
97  }
98 
100  ~CvodesInterface() override;
101 
102  // Get name of the plugin
103  const char* plugin_name() const override { return "cvodes";}
104 
105  // Get name of the class
106  std::string class_name() const override { return "CvodesInterface";}
107 
109 
110  static const Options options_;
111  const Options& get_options() const override { return options_;}
112  double min_step_size_;
113  bool always_recalculate_jacobian_;
115 
116 
118  void init(const Dict& opts) override;
119 
121  void* alloc_mem() const override { return new CvodesMemory(*this);}
122 
124  int init_mem(void* mem) const override;
125 
127  void free_mem(void *mem) const override { delete static_cast<CvodesMemory*>(mem);}
128 
130  void reset(IntegratorMemory* mem,
131  const double* u, const double* x, const double* z, const double* p) const override;
132 
134  void advance(IntegratorMemory* mem,
135  const double* u, double* x, double* z, double* q) const override;
136 
138  void impulseB(IntegratorMemory* mem,
139  const double* rx, const double* rz, const double* rp) const override;
140 
142  void retreat(IntegratorMemory* mem, const double* u,
143  double* rx, double* rq, double* uq) const override;
144 
146  static CvodesMemory* to_mem(void *mem) {
147  CvodesMemory* m = static_cast<CvodesMemory*>(mem);
148  casadi_assert_dev(m);
149  return m;
150  }
151 
153  static const std::string meta_doc;
154 
155  protected:
156 
157  // Sundials callback functions
158  static void ehfun(int error_code, const char *module, const char *function, char *msg,
159  void *user_data);
160  static int rhsF(double t, N_Vector x, N_Vector xdot, void *user_data);
161  static int rhsB(double t, N_Vector x, N_Vector xB, N_Vector xdotB, void *user_data);
162  static int rhsQF(double t, N_Vector x, N_Vector qdot, void *user_data);
163  static int rhsQB(double t, N_Vector x, N_Vector rx, N_Vector ruqdot, void *user_data);
164  static int jtimesF(N_Vector v, N_Vector Jv, double t, N_Vector x, N_Vector xdot,
165  void *user_data, N_Vector tmp);
166  static int jtimesB(N_Vector vB, N_Vector JvB, double t, N_Vector x, N_Vector xB,
167  N_Vector xdotB, void *user_data , N_Vector tmpB);
168  static int psolveF(double t, N_Vector x, N_Vector xdot, N_Vector r, N_Vector z,
169  double gamma, double delta, int lr, void *user_data, N_Vector tmp);
170  static int psolveB(double t, N_Vector x, N_Vector xB, N_Vector xdotB, N_Vector rvecB,
171  N_Vector zvecB, double gammaB, double deltaB,
172  int lr, void *user_data, N_Vector tmpB);
173  static int psetupF(double t, N_Vector x, N_Vector xdot, booleantype jok,
174  booleantype *jcurPtr, double gamma, void *user_data,
175  N_Vector tmp1, N_Vector tmp2, N_Vector tmp3);
176  static int psetupB(double t, N_Vector x, N_Vector xB, N_Vector xdotB,
177  booleantype jokB, booleantype *jcurPtrB, double gammaB,
178  void *user_data, N_Vector tmp1B, N_Vector tmp2B, N_Vector tmp3B);
179  static int lsetupF(CVodeMem cv_mem, int convfail, N_Vector x, N_Vector xdot,
180  booleantype *jcurPtr, N_Vector vtemp1, N_Vector vtemp2, N_Vector vtemp3);
181  static int lsolveF(CVodeMem cv_mem, N_Vector b, N_Vector weight, N_Vector x, N_Vector xdot);
182  static int lsetupB(CVodeMem cv_mem, int convfail, N_Vector x, N_Vector xdot,
183  booleantype *jcurPtr, N_Vector vtemp1, N_Vector vtemp2, N_Vector vtemp3);
184  static int lsolveB(CVodeMem cv_mem, N_Vector b, N_Vector weight, N_Vector x, N_Vector xdot);
185 
186  // Throw error
187  static void cvodes_error(const char* module, int flag);
188 
189  casadi_int lmm_; // linear multistep method
190  casadi_int iter_; // nonlinear solver iteration
191 
192  public:
193 
195  void serialize_body(SerializingStream &s) const override;
196 
198  static ProtoFunction* deserialize(DeserializingStream& s) { return new CvodesInterface(s); }
199 
200  protected:
201 
203  explicit CvodesInterface(DeserializingStream& s);
204 };
205 
206 } // namespace casadi
207 
209 #endif // CASADI_CVODES_INTERFACE_HPP
The casadi namespace.
GenericType::Dict Dict
C++ equivalent of Python's dict or MATLAB's struct.