fmu_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 #ifndef CASADI_FMU_IMPL_HPP
26 #define CASADI_FMU_IMPL_HPP
27 
28 #include "fmu.hpp"
29 #include "importer.hpp"
30 #include "shared_object_internal.hpp"
31 
33 
34 namespace casadi {
35 
36 // Forward declarations
37 class DaeBuilderInternal;
38 struct FmuMemory;
39 struct InputStruct;
40 
49 class CASADI_EXPORT FmuInternal : public SharedObjectInternal {
50  friend class Fmu;
51  public:
52  // Constructor
53  FmuInternal(const std::string& name,
54  const std::vector<std::string>& scheme_in, const std::vector<std::string>& scheme_out,
55  const std::map<std::string, std::vector<size_t>>& scheme, const std::vector<std::string>& aux);
56 
58  ~FmuInternal() override;
59 
60  // Initialize
61  virtual void init(const DaeBuilderInternal* dae) = 0;
62 
63  // Finalize
64  virtual void finalize() = 0;
65 
69  void disp(std::ostream& stream, bool more) const override;
70 
74  size_t n_in() const { return iind_.size();}
75 
79  size_t n_out() const { return oind_.size();}
80 
81  // Index lookup for input
82  size_t index_in(const std::string& n) const;
83 
84  // Index lookup for output
85  size_t index_out(const std::string& n) const;
86 
87  // Does the FMU support analytic derivatives?
88  virtual bool has_ad() const = 0;
89 
90  // Get Jacobian sparsity for a subset of inputs and outputs
91  Sparsity jac_sparsity(const std::vector<size_t>& osub, const std::vector<size_t>& isub) const;
92 
93  // Get Hessian sparsity for a subset of inputs
94  Sparsity hess_sparsity(const std::vector<size_t>& r, const std::vector<size_t>& c) const;
95 
97 
100  std::vector<double> all_nominal_in(size_t i) const;
101  std::vector<double> all_nominal_out(size_t i) const;
103 
104  // Print description of an input
105  std::string desc_in(FmuMemory* m, size_t id, bool more = true) const;
106 
107  // Load an FMI function
108  template<typename T>
109  T* load_function(const std::string& symname);
110 
114  virtual int init_mem(FmuMemory* m) const = 0;
115 
116  // Free FMU instance
117  virtual void free_instance(void* c) const = 0;
118 
119  // Set value
120  void set(FmuMemory* m, size_t ind, const double* value) const;
121 
122  // Request the calculation of a variable
123  void request(FmuMemory* m, size_t ind) const;
124 
125  // Calculate all requested variables
126  virtual int eval(FmuMemory* m) const = 0;
127 
128  // Get a calculated variable
129  void get(FmuMemory* m, size_t id, double* value) const;
130 
131  // Set seed
132  void set_seed(FmuMemory* m, casadi_int nseed,
133  const casadi_int* id, const double* v) const;
134 
135  // Request the calculation of a sensitivity
136  void request_sens(FmuMemory* m, casadi_int nsens, const casadi_int* id,
137  const casadi_int* wrt_id) const;
138 
139  // Set all forward seeds for a single input
140  void set_fwd(FmuMemory* m, size_t ind, const double* v) const;
141 
142  // Request the calculation of all forward sensitivities for an output
143  void request_fwd(FmuMemory* m, casadi_int ind) const;
144 
145  // Get the forward sensitivities for a single output
146  void get_fwd(FmuMemory* m, size_t ind, double* v) const;
147 
148  // Calculate directional derivatives
149  int eval_derivative(FmuMemory* m, bool independent_seeds) const;
150 
151  // Calculate directional derivatives using AD
152  virtual int eval_ad(FmuMemory* m) const = 0;
153 
154  // Calculate directional derivatives using FD
155  virtual int eval_fd(FmuMemory* m, bool independent_seeds) const = 0;
156 
157  // Get calculated derivatives
158  void get_sens(FmuMemory* m, casadi_int nsens,
159  const casadi_int* id, double* v) const;
160 
161  // Gather user sensitivities
162  void gather_sens(FmuMemory* m) const;
163 
164  // Gather user inputs and outputs
165  void gather_io(FmuMemory* m) const;
166 
170  virtual void get_stats(FmuMemory* m, Dict* stats,
171  const std::vector<std::string>& name_in, const InputStruct* in) const = 0;
172 
173  void serialize(SerializingStream& s) const;
174 
175  virtual void serialize_type(SerializingStream& s) const;
176  virtual void serialize_body(SerializingStream& s) const;
177 
178  static FmuInternal* deserialize(DeserializingStream& s);
179 
180  protected:
181  explicit FmuInternal(DeserializingStream& s);
182 
184  std::string name_;
185 
186  // IO scheme
187  std::vector<std::string> scheme_in_, scheme_out_;
188  std::map<std::string, std::vector<size_t>> scheme_;
189 
190  // Auxilliary outputs
191  std::vector<std::string> aux_;
192 
194  Importer li_;
195 
196  // Mapping from scheme variable to and from FMU variable indices
197  std::vector<size_t> iind_, iind_map_, oind_, oind_map_;
198 
199  // Meta information about the input/output variable subsets
200  std::vector<double> nominal_in_, nominal_out_;
201  std::vector<double> min_in_, min_out_;
202  std::vector<double> max_in_, max_out_;
203  std::vector<std::string> vn_in_, vn_out_;
204  std::vector<unsigned int> vr_in_, vr_out_;
205 
206  // Numerical values for inputs
207  std::vector<double> value_in_;
208 
209  // Reduced space indices for all inputs and outputs
210  std::vector<std::vector<size_t>> ired_, ored_;
211 
212  // Sparsity pattern for extended Jacobian, Hessian
213  Sparsity jac_sp_, hess_sp_;
214 };
215 
216 template<typename T>
217 T* FmuInternal::load_function(const std::string& symname) {
218  // Load the function
219  signal_t f = li_.get_function(symname);
220  // Ensure that it was found
221  casadi_assert(f != 0, "Cannot retrieve '" + symname + "'");
222  // Return function with the right type
223  return reinterpret_cast<T*>(f);
224 }
225 
226 } // namespace casadi
227 
229 
230 #endif // CASADI_FMU_IMPL_HPP
The casadi namespace.
GenericType::Dict Dict
C++ equivalent of Python's dict or MATLAB's struct.