kinsol_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_KINSOL_INTERFACE_HPP
27 #define CASADI_KINSOL_INTERFACE_HPP
28 
29 #include <casadi/interfaces/sundials/casadi_rootfinder_kinsol_export.h>
30 #include "casadi/core/rootfinder_impl.hpp"
31 #include <nvector/nvector_serial.h> /* serial N_Vector types, fcts., and macros */
32 #include <sundials/sundials_dense.h> /* definitions DlsMat DENSE_ELEM */
33 #include <sundials/sundials_types.h> /* definition of type double */
34 #include <kinsol/kinsol.h> /* prototypes for CVode fcts. and consts. */
35 #include <kinsol/kinsol_dense.h>
36 #include <kinsol/kinsol_band.h>
37 #include <kinsol/kinsol_spgmr.h>
38 #include <kinsol/kinsol_spbcgs.h>
39 #include <kinsol/kinsol_sptfqmr.h>
40 #include <kinsol/kinsol_impl.h> /* Needed for the provided linear solver */
41 #include <kinsol/kinsol_spils_impl.h> /* Needed for the provided linear solver */
42 #include <ctime>
43 
53 namespace casadi {
55  class KinsolInterface;
56 
57  // Memory
58  struct KinsolMemory : public RootfinderMemory {
60  const KinsolInterface& self;
61 
63  KinsolMemory(const KinsolInterface& s);
64 
66  ~KinsolMemory();
67 
69  void* mem;
70 
72  N_Vector u;
73 
74  // Current Jacobian
75  double* jac;
76 
77  // Return status
78  std::string return_status;
79  };
80 
86  class KinsolInterface : public Rootfinder {
87  public:
89  explicit KinsolInterface(const std::string& name, const Function& f);
90 
92  ~KinsolInterface() override;
93 
95  static Rootfinder* creator(const std::string& name, const Function& f) {
96  return new KinsolInterface(name, f);
97  }
98 
100 
101  static const Options options_;
102  const Options& get_options() const override { return options_;}
104 
106  void init(const Dict& opts) override;
107 
109  int solve(void* mem) const override;
110 
111  // Get name of the plugin
112  const char* plugin_name() const override { return "kinsol";}
113 
114  // Get name of the class
115  std::string class_name() const override { return "KinsolInterface";}
116 
117  // Scaling
118  N_Vector u_scale_, f_scale_;
119 
121  casadi_int strategy_;
122 
123  // Should KINSOL internal warning messages be ignored
124  bool disable_internal_warnings_;
125 
126  // Maximum number of iterations
127  casadi_int max_iter_;
128 
129  // Print information about iterations
130  casadi_int print_level_;
131 
132  // Use exact Jacobian?
133  bool exact_jac_;
134 
135  // Type of linear solver
136  enum LinsolType { DENSE, BANDED, ITERATIVE, USER_DEFINED};
137  LinsolType linear_solver_type_;
138 
139  // Bandwidth (for banded solvers)
140  casadi_int upper_bandwidth_, lower_bandwidth_;
141 
142  // Krylov subspace size (for iterative solvers)
143  casadi_int maxl_;
144 
145  // Iterative solver
146  enum IterativeSolver { GMRES, BCGSTAB, TFQMR};
147  IterativeSolver iterative_solver_;
148 
149  // Should a preconditioner be used
150  bool use_preconditioner_;
151 
152  // Absolute tolerance
153  double abstol_;
154 
155  // Jacobian times vector function
156  Function jtimes_;
157 
158  // Get jtimes_
159  void get_jtimes();
160 
161  // Raise an error specific to KinSol
162  void kinsol_error(const std::string& module, int flag, bool fatal=true) const;
163 
165  static const std::string meta_doc;
166 
168  void* alloc_mem() const override { return new KinsolMemory(*this);}
169 
171  int init_mem(void* mem) const override;
172 
174  Dict get_stats(void* mem) const override;
175 
177  void free_mem(void *mem) const override { delete static_cast<KinsolMemory*>(mem);}
178 
180  void set_work(void* mem, const double**& arg, double**& res,
181  casadi_int*& iw, double*& w) const override;
182 
184  static KinsolMemory* to_mem(void *mem) {
185  KinsolMemory* m = static_cast<KinsolMemory*>(mem);
186  casadi_assert_dev(m);
187  return m;
188  }
189 
191  void func(KinsolMemory& m, N_Vector u, N_Vector fval) const;
192  void djac(KinsolMemory& m, long N, N_Vector u, N_Vector fu,
193  DlsMat J, N_Vector tmp1, N_Vector tmp2) const;
194  void bjac(KinsolMemory& m, long N, long mupper, long mlower, N_Vector u, N_Vector fu, DlsMat J,
195  N_Vector tmp1, N_Vector tmp2) const;
196  void jtimes(KinsolMemory& m, N_Vector v, N_Vector Jv, N_Vector u, int* new_u) const;
197  void psetup(KinsolMemory& m, N_Vector u, N_Vector uscale, N_Vector fval, N_Vector fscale,
198  N_Vector tmp1, N_Vector tmp2) const;
199  void psolve(KinsolMemory& m, N_Vector u, N_Vector uscale,
200  N_Vector fval, N_Vector fscale, N_Vector v, N_Vector tmp) const;
201 
203  static int func_wrapper(N_Vector u, N_Vector fval, void *user_data);
204  static int djac_wrapper(long N, N_Vector u, N_Vector fu, DlsMat J, void *user_data,
205  N_Vector tmp1, N_Vector tmp2);
206  static int bjac_wrapper(long N, long mupper, long mlower, N_Vector u, N_Vector fu, DlsMat J,
207  void *user_data, N_Vector tmp1, N_Vector tmp2);
208  static int jtimes_wrapper(N_Vector v, N_Vector Jv, N_Vector u, int* new_u, void *user_data);
209  static int psetup_wrapper(N_Vector u, N_Vector uscale, N_Vector fval, N_Vector fscale,
210  void* user_data, N_Vector tmp1, N_Vector tmp2);
211  static int psolve_wrapper(N_Vector u, N_Vector uscale, N_Vector fval, N_Vector fscale,
212  N_Vector v, void* user_data, N_Vector tmp);
213 
215  static int lsetup(KINMem kin_mem);
216  static int lsolve(KINMem kin_mem, N_Vector x, N_Vector b, double *sJpnorm, double *sFdotJp);
217  static void ehfun(int error_code, const char *module, const char *function,
218  char *msg, void *eh_data);
219  static void ihfun(const char *module, const char *function, char *msg, void *ih_data);
220  };
221 
222 } // namespace casadi
223 
225 #endif // CASADI_KINSOL_INTERFACE_HPP
The casadi namespace.
Definition: archiver.hpp:32
GenericType::Dict Dict
C++ equivalent of Python's dict or MATLAB's struct.