fmu_function.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_FMU_FUNCTION_HPP
27 #define CASADI_FMU_FUNCTION_HPP
28 
29 #include "function_internal.hpp"
30 #include "fmu.hpp"
31 #include "finite_differences.hpp"
32 
34 
35 namespace casadi {
36 
37 // Forward declarations
38 class DaeBuilderInternal;
39 class FmuFunction;
40 struct InputStruct;
41 
42 // Memory object
43 struct CASADI_EXPORT FmuMemory : public FunctionMemory {
44  // Function object
45  const FmuFunction& self;
46  // Evaluation inputs
47  const double** arg;
48  // Evaluation outputs
49  double** res;
50  // Extended Jacobian
51  double *jac_nz;
52  // Extended Hessian
53  double *hess_nz;
54  // Adjoint seeds, sensitivities being calculated
55  double *aseed, *asens, *pert_asens;
56  // Memory for Jacobian calculation
57  casadi_jac_data<double> jac_data, adj_data;
58  // Instance memory
59  void* instance;
60  // Additional (slave) memory objects
61  std::vector<FmuMemory*> slaves;
62  // Input and output buffers
63  std::vector<double> ibuf_, obuf_;
64  // Seeds, sensitivities
65  std::vector<double> isens_, osens_;
66  // Which inputs and outputs have been marked
67  std::vector<bool> imarked_, omarked_;
68  // Derivative with respect to
69  std::vector<size_t> wrt_;
70  // Current known/unknown variables
71  std::vector<size_t> id_in_, id_out_;
72  // Which perturbations are permitted
73  std::vector<bool> in_bounds_;
74  // Flip sign?
75  std::vector<bool> flip_;
76  // Value references
77  std::vector<unsigned int> vr_in_, vr_out_;
78  // Work vector (reals)
79  std::vector<double> v_in_, v_out_, d_in_, d_out_, fd_out_, v_pert_;
80  // Constructor
81  explicit FmuMemory(const FmuFunction& self) : self(self), instance(nullptr) {}
82 };
83 
85 enum class Parallelization {SERIAL, OPENMP, THREAD, NUMEL};
86 
88 CASADI_EXPORT std::string to_string(Parallelization v);
89 
90 // Types of inputs
91 enum class InputType {REG, FWD, ADJ, OUT, ADJ_OUT};
92 
93 // Input structure
94 struct CASADI_EXPORT InputStruct {
95  // Type of input
96  InputType type;
97  // Corresponding index in Fmu
98  size_t ind;
99  // Parse an input string
100  static InputStruct parse(const std::string& n, const Fmu* fmu,
101  std::vector<std::string>* name_in = nullptr,
102  std::vector<std::string>* name_out = nullptr);
103 };
104 
105 // Types of inputs
106 enum class OutputType {REG, FWD, ADJ, JAC, JAC_TRANS, JAC_ADJ_OUT, JAC_REG_ADJ, HESS};
107 
108 // Output structure
109 struct CASADI_EXPORT OutputStruct {
110  // Type of input
111  OutputType type;
112  // Output index in Fmu
113  size_t ind;
114  // With-respect-to index in Fmu
115  size_t wrt;
116  // Selection
117  size_t rbegin, rend, cbegin, cend;
118  // Parse an output string
119  static OutputStruct parse(const std::string& n, const Fmu* fmu,
120  std::vector<std::string>* name_in = nullptr,
121  std::vector<std::string>* name_out = nullptr);
122  // Constructor
123  OutputStruct() : ind(-1), wrt(-1), rbegin(-1), rend(-1), cbegin(-1), cend(-1) {}
124 };
125 
126 // Helper function
127 CASADI_EXPORT bool has_prefix(const std::string& s);
128 
129 // Split prefix
130 CASADI_EXPORT std::string pop_prefix(const std::string& s, std::string* rem = nullptr);
131 
132 class CASADI_EXPORT FmuFunction : public FunctionInternal {
133  public:
134  // FMU (shared between derivative expressions
135  Fmu fmu_;
136 
137  // Information about function inputs
138  std::vector<InputStruct> in_;
139 
140  // Information about function outputs
141  std::vector<OutputStruct> out_;
142 
143  // All Jacobian inputs and outputs
144  std::vector<size_t> jac_in_, jac_out_;
145 
146  // Nominal values for Jacobian inputs
147  std::vector<double> jac_nom_in_;
148 
149  // Sparsity of transpose (if needed)
150  std::vector<Sparsity> sp_trans_;
151  std::vector<casadi_int> sp_trans_map_;
152 
153  // What blocks exist?
154  bool has_jac_, has_fwd_, has_adj_, has_hess_;
155 
156  // Override provides_directional_derivatives, provides_adjoint_derivatives
157  bool uses_directional_derivatives_, uses_adjoint_derivatives_;
158 
160  casadi_int nfwd_, nadj_;
161 
162  // Validate derivative calculations: Move to base class?
163  bool validate_forward_, validate_hessian_;
164 
165  // User-set options
166  double step_, abstol_, reltol_;
167  bool print_progress_, new_jacobian_, new_forward_, new_hessian_, fd_flip_,
168  make_symmetric_, hessian_coloring_, asymmetric_hessian_coloring_,
169  enable_forward_jacobian_, enable_adjoint_jacobian_, enable_adjoint_hessian_;
170  std::string validate_ad_file_;
171 
172  // FD method as an enum
173  FdMode fd_;
174 
175  // Types of parallelization
176  Parallelization parallelization_;
177 
178  // Stats from initialization
179  Dict init_stats_;
180 
184  FmuFunction(const std::string& name, const Fmu& fmu,
185  const std::vector<std::string>& name_in,
186  const std::vector<std::string>& name_out);
187 
191  ~FmuFunction() override;
192 
196  std::string class_name() const override { return "FmuFunction";}
197 
199 
202  static const Options options_;
203  const Options& get_options() const override { return options_;}
205 
207  void init(const Dict& opts) override;
208 
209  // Identify input and output schemes from FmuFunction inputs and outputs
210  static void identify_io(
211  std::vector<std::string>* scheme_in,
212  std::vector<std::string>* scheme_out,
213  const std::vector<std::string>& name_in,
214  const std::vector<std::string>& name_out);
215 
216  // Get sparsity pattern for extended Jacobian, Hessian
217  Sparsity jac_sp_, hess_sp_, adj_sp_;
218 
219  // Graph coloring
220  Sparsity jac_colors_, adj_colors_, hess_colors_, hess_uni_colors_;
221 
222  // Which color is used to calculate a given nonzero in the Hessian?
223  std::vector<casadi_int> which_hess_color_;
224 
225  // Nonlinearly entering variables
226  std::vector<casadi_int> nonlin_;
227 
228  // Jacobian memory
229  casadi_jac_prob<double> jac_prob_, adj_prob_;
230 
231  // Number of parallel tasks
232  casadi_int max_jac_tasks_, max_hess_tasks_, max_adj_tasks_, max_n_tasks_;
233 
235 
238  size_t get_n_in() override { return in_.size();}
239  size_t get_n_out() override {return out_.size();}
241 
243 
246  Sparsity get_sparsity_in(casadi_int i) override;
247  Sparsity get_sparsity_out(casadi_int i) override;
249 
251 
254  std::vector<double> get_nominal_in(casadi_int i) const override;
255  std::vector<double> get_nominal_out(casadi_int i) const override;
257 
258  // Evaluate numerically
259  int eval(const double** arg, double** res, casadi_int* iw, double* w, void* mem) const override;
260 
261  // Evaluate all tasks numerically, serially or in parallel
262  int eval_all(FmuMemory* m, casadi_int n_task,
263  bool need_nondiff, bool need_jac, bool need_fwd, bool need_adj, bool need_hess) const;
264 
265  // Evaluate numerically, single thread
266  int eval_task(FmuMemory* m, casadi_int task, casadi_int n_task,
267  bool need_nondiff, bool need_jac, bool need_fwd, bool need_adj, bool need_hess) const;
268 
269  // Finalize Hessian creation
270  void finalize_hessian(FmuMemory* m, double *hess_nz, casadi_int* iw) const;
271 
273 
276  bool has_jac_sparsity(casadi_int oind, casadi_int iind) const override;
277  Sparsity get_jac_sparsity(casadi_int oind, casadi_int iind, bool symmetric) const override;
279 
280  // Are all inputs/outputs regular?
281  bool all_regular() const;
282 
283  // Are all inputs/outputs vectors (i.e. not Jacobian or Hessian blocks)?
284  bool all_vectors() const;
285 
286  // Factory
287  Function factory(const std::string& name,
288  const std::vector<std::string>& s_in,
289  const std::vector<std::string>& s_out,
290  const Function::AuxOut& aux,
291  const Dict& opts) const override;
292 
294 
297  bool has_jacobian() const override;
298  Function get_jacobian(const std::string& name,
299  const std::vector<std::string>& inames,
300  const std::vector<std::string>& onames,
301  const Dict& opts) const override;
303 
305 
308  bool has_forward(casadi_int nfwd) const override;
309  Function get_forward(casadi_int nfwd, const std::string& name,
310  const std::vector<std::string>& inames,
311  const std::vector<std::string>& onames,
312  const Dict& opts) const override;
314 
316 
319  bool has_reverse(casadi_int nadj) const override;
320  Function get_reverse(casadi_int nadj, const std::string& name,
321  const std::vector<std::string>& inames,
322  const std::vector<std::string>& onames,
323  const Dict& opts) const override;
325 
331  void check_mem_count(casadi_int n) const override;
332 
336  void* alloc_mem() const override;
337 
341  int init_mem(void* mem) const override;
342 
346  void free_mem(void *mem) const override;
347 
349  Dict get_stats(void* mem) const override;
350 
354  void serialize_body(SerializingStream &s) const override;
355 
359  static ProtoFunction* deserialize(DeserializingStream& s) { return new FmuFunction(s); }
360 
364  void change_option(const std::string& option_name, const GenericType& option_value) override;
365 
366  protected:
370  explicit FmuFunction(DeserializingStream& s);
371 };
372 
373 } // namespace casadi
375 
376 #endif // CASADI_FMU_FUNCTION_HPP
std::map< std::string, std::vector< std::string > > AuxOut
Definition: function.hpp:447
The casadi namespace.
Definition: archiver.hpp:32
GenericType::Dict Dict
C++ equivalent of Python's dict or MATLAB's struct.