casadi_fmu.hpp
1 //
2 // MIT No Attribution
3 //
4 // Copyright (C) 2010-2023 Joel Andersson, Joris Gillis, Moritz Diehl, KU Leuven.
5 //
6 // Permission is hereby granted, free of charge, to any person obtaining a copy of this
7 // software and associated documentation files (the "Software"), to deal in the Software
8 // without restriction, including without limitation the rights to use, copy, modify,
9 // merge, publish, distribute, sublicense, and/or sell copies of the Software, and to
10 // permit persons to whom the Software is furnished to do so.
11 //
12 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
13 // INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
14 // PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
15 // HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
16 // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
17 // SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
18 //
19 
20 typedef struct {
21  // Name of instance
22  const char* instance_name;
23  // Value for all variables
24  double v[SZ_MEM];
25  // Value for derivatives
26  double d[SZ_MEM];
27  // Has any variable been set since last call
29  // Did continuous states change?
31  // Buffers for evaluation generated code
32  double t;
33  double p[N_P];
34  double x[N_X];
35  double xdot[N_X];
36  double u[N_U];
37  double y[N_Y];
38  double zero[N_ZERO];
39  // Event trigger?
40  int zeroind;
41  // Which events can trigger
42  int triggerable[N_ZERO];
43  // Buffers for derivative calculations
44  double dp[N_P];
45  double dx[N_X];
46  double dxdot[N_X];
47  double du[N_U];
48  double dy[N_Y];
49  double dzero[N_ZERO];
50  // Work vectors for evaluation
51  const double* arg[SZ_ARG];
52  double* res[SZ_RES];
53  casadi_int iw[SZ_IW];
54  double w[SZ_W];
56 
57 int evaluate(casadi_fmi_memory* m) {
58  // Local variables
59  size_t i;
60  int mem, flag;
61  // Copy states, inputs and parameters to input buffers
62  for (i = 0; i < N_X; ++i) m->x[i] = m->v[x_vr[i]];
63  for (i = 0; i < N_P; ++i) m->p[i] = m->v[p_vr[i]];
64  for (i = 0; i < N_U; ++i) m->u[i] = m->v[u_vr[i]];
65 
66  // Map inputs to evaluation buffer
67  i = 0;
68  m->arg[i++] = &m->t;
69  m->arg[i++] = m->x;
70  m->arg[i++] = m->p;
71  m->arg[i++] = m->u;
72 
73  // Map outputs to evaluation buffer
74  i = 0;
75  m->res[i++] = m->xdot;
76  m->res[i++] = m->y;
77  m->res[i++] = m->zero;
78 
79  // Evaluate
80  mem = MODELNAME_checkout();
81  flag = MODELNAME(m->arg, m->res, m->iw, m->w, mem);
82  MODELNAME_release(mem);
83 
84  // Copy from output buffers
85  for (i = 0; i < N_X; ++i) m->v[xdot_vr[i]] = m->xdot[i];
86  for (i = 0; i < N_Y; ++i) m->v[y_vr[i]] = m->y[i];
87  for (i = 0; i < N_ZERO; ++i) m->v[zero_vr[i]] = m->zero[i];
88 
89  return flag;
90 }
91 
92 int evaluate_forward(casadi_fmi_memory* m) {
93  // Local variables
94  size_t i;
95  int mem, flag;
96  // Copy seeds for states, inputs and parameters to input buffers
97  for (i = 0; i < N_X; ++i) m->dx[i] = m->d[x_vr[i]];
98  for (i = 0; i < N_P; ++i) m->dp[i] = m->d[p_vr[i]];
99  for (i = 0; i < N_U; ++i) m->du[i] = m->d[u_vr[i]];
100 
101  // Map nondifferentiated inputs to evaluation buffer
102  i = 0;
103  m->arg[i++] = 0; // t
104  m->arg[i++] = m->x;
105  m->arg[i++] = m->p;
106  m->arg[i++] = m->u;
107 
108  // Map nondifferentiated outputs to evaluation buffer
109  m->arg[i++] = m->xdot;
110  m->arg[i++] = m->y;
111  m->arg[i++] = m->zero;
112 
113  // Map forward seeds
114  m->arg[i++] = 0;
115  m->arg[i++] = m->dx;
116  m->arg[i++] = m->dp;
117  m->arg[i++] = m->du;
118 
119  // Map forward sensitivities
120  i = 0;
121  m->res[i++] = m->dxdot;
122  m->res[i++] = m->dy;
123  m->res[i++] = m->dzero;
124 
125  // Evaluate
126  mem = fwd1_MODELNAME_checkout();
127  flag = fwd1_MODELNAME(m->arg, m->res, m->iw, m->w, mem);
128  fwd1_MODELNAME_release(mem);
129 
130  // Copy from output buffers
131  for (i = 0; i < N_X; ++i) m->d[xdot_vr[i]] = m->dxdot[i];
132  for (i = 0; i < N_Y; ++i) m->d[y_vr[i]] = m->dy[i];
133  for (i = 0; i < N_ZERO; ++i) m->d[zero_vr[i]] = m->dzero[i];
134 
135  // Return evaluation flag
136  return flag;
137 }
138 
139 int evaluate_adjoint(casadi_fmi_memory* m) {
140  // Local variables
141  size_t i;
142  int mem, flag;
143  // Copy seeds for output buffers
144  for (i = 0; i < N_X; ++i) m->dxdot[i] = m->d[xdot_vr[i]];
145  for (i = 0; i < N_Y; ++i) m->dy[i] = m->d[y_vr[i]];
146  for (i = 0; i < N_ZERO; ++i) m->dzero[i] = m->d[zero_vr[i]];
147 
148  // Clear sensitivities
149  for (i = 0; i < N_X; ++i) m->dx[i] = 0;
150  for (i = 0; i < N_P; ++i) m->dp[i] = 0;
151  for (i = 0; i < N_U; ++i) m->du[i] = 0;
152 
153  // Map nondifferentiated inputs to evaluation buffer
154  i = 0;
155  m->arg[i++] = 0; // t
156  m->arg[i++] = m->x;
157  m->arg[i++] = m->p;
158  m->arg[i++] = m->u;
159 
160  // Map nondifferentiated outputs to evaluation buffer
161  m->arg[i++] = m->xdot;
162  m->arg[i++] = m->y;
163  m->arg[i++] = m->zero;
164 
165  // Map adjoint seeds
166  m->arg[i++] = m->dxdot;
167  m->arg[i++] = m->dy;
168  m->arg[i++] = m->dzero;
169 
170  // Map adjoint sensitivities
171  i = 0;
172  m->res[i++] = 0; // t
173  m->res[i++] = m->dx;
174  m->res[i++] = m->dp;
175  m->res[i++] = m->du;
176 
177  // Evaluate
178  mem = adj1_MODELNAME_checkout();
179  flag = adj1_MODELNAME(m->arg, m->res, m->iw, m->w, mem);
180  adj1_MODELNAME_release(mem);
181 
182  // Copy from input buffers
183  for (i = 0; i < N_X; ++i) m->d[x_vr[i]] = m->dx[i];
184  for (i = 0; i < N_P; ++i) m->d[p_vr[i]] = m->dp[i];
185  for (i = 0; i < N_U; ++i) m->d[u_vr[i]] = m->du[i];
186 
187  // Return evaluation flag
188  return flag;
189 }
190 
191 #if N_ZERO > 0
192 
193 int evaluate_transition(casadi_fmi_memory* m) {
194  // Local variables
195  size_t i;
196  int mem, flag;
197  double zeroind;
198 
199  // Cast event index to double
200  zeroind = (double)m->zeroind;
201 
202  // Copy states, inputs and parameters to input buffers
203  for (i = 0; i < N_X; ++i) m->x[i] = m->v[x_vr[i]];
204  for (i = 0; i < N_P; ++i) m->p[i] = m->v[p_vr[i]];
205  for (i = 0; i < N_U; ++i) m->u[i] = m->v[u_vr[i]];
206 
207  // Map inputs to evaluation buffer
208  i = 0;
209  m->arg[i++] = &zeroind; // index
210  m->arg[i++] = &m->t; // t
211  m->arg[i++] = m->x; // x
212  m->arg[i++] = 0; // z
213  m->arg[i++] = m->p; // p
214  m->arg[i++] = m->u; // u
215 
216  // Map outputs to evaluation buffer
217  i = 0;
218  m->res[i++] = m->xdot; // post_x
219  m->res[i++] = 0; // post_z
220 
221  // Evaluate
222  mem = transition_MODELNAME_checkout();
223  flag = transition_MODELNAME(m->arg, m->res, m->iw, m->w, mem);
224  transition_MODELNAME_release(mem);
225 
226  // Copy from output buffers
227  for (i = 0; i < N_X; ++i) m->v[x_vr[i]] = m->xdot[i];
228 
229  return flag;
230 }
231 #endif // N_ZERO > 0
232 
233 FMI3_Export fmi3Status fmi3Reset(fmi3Instance instance) {
234  // Local variables
235  size_t i;
237  // Cast to memory struct
238  m = (casadi_fmi_memory*)instance;
239  // Initialize variables
240  for (i = 0; i < SZ_MEM; ++i) m->v[i] = start[i];
241  // Reset derivative buffer
242  for (i = 0; i < SZ_MEM; ++i) m->d[i] = 0;
243  // Not evaluated
244  m->up_to_date = 0;
245  // Zero index is negative: No event
246  m->zeroind = -1;
248  // Do not permit events to be triggered unless they have been strictly positive
249  for (i = 0; i < N_ZERO; ++i) m->triggerable[i] = 0;
250  // Always successful return
251  return fmi3OK;
252 }
253 
254 FMI3_Export fmi3Instance fmi3InstantiateModelExchange(
255  fmi3String instanceName,
256  fmi3String instantiationToken,
257  fmi3String resourcePath,
258  fmi3Boolean visible,
259  fmi3Boolean loggingOn,
260  fmi3InstanceEnvironment instanceEnvironment,
261  fmi3LogMessageCallback logMessage) {
262  // Local variables
264  // Unused variables
265  (void)resourcePath; // unused
266  (void)visible; // unused
267  (void)loggingOn; // unused
268  (void)instanceEnvironment; // unused
269  (void)logMessage; // unused
270  // Allocate memory structure
271  m = (casadi_fmi_memory*)malloc(sizeof(casadi_fmi_memory));
272  // If allocation was successful
273  if (m) {
274  // Increase counters for codegen
275  MODELNAME_incref();
276 #if N_ZERO > 0
277  transition_MODELNAME_incref();
278 #endif // N_ZERO > 0
279  // Copy meta data
280  m->instance_name = instanceName;
281  // Call reset function (return flag does not need to be checked)
282  (void)fmi3Reset(m);
283  }
284  // Return pointer to instance, or null
285  return m;
286 }
287 
288 FMI3_Export fmi3Instance fmi3InstantiateCoSimulation(fmi3String instanceName,
289  fmi3String instantiationToken,
290  fmi3String resourcePath,
291  fmi3Boolean visible,
292  fmi3Boolean loggingOn,
293  fmi3Boolean eventModeUsed,
294  fmi3Boolean earlyReturnAllowed,
295  const fmi3ValueReference requiredIntermediateVariables[],
296  size_t nRequiredIntermediateVariables,
297  fmi3InstanceEnvironment instanceEnvironment,
298  fmi3LogMessageCallback logMessage,
299  fmi3IntermediateUpdateCallback intermediateUpdate) {
300  // Not implemented
301  return 0;
302 }
303 
304 FMI3_Export fmi3Instance fmi3InstantiateScheduledExecution(fmi3String instanceName,
305  fmi3String instantiationToken,
306  fmi3String resourcePath,
307  fmi3Boolean visible,
308  fmi3Boolean loggingOn,
309  fmi3InstanceEnvironment instanceEnvironment,
310  fmi3LogMessageCallback logMessage,
311  fmi3ClockUpdateCallback clockUpdate,
312  fmi3LockPreemptionCallback lockPreemption,
313  fmi3UnlockPreemptionCallback unlockPreemption) {
314  // Not implemented
315  return 0;
316 }
317 
318 FMI3_Export fmi3Status fmi3GetNumberOfVariableDependencies(fmi3Instance instance,
319  fmi3ValueReference valueReference,
320  size_t* nDependencies) {
321  // Not implemented
322  return fmi3Fatal;
323 }
324 
325 FMI3_Export fmi3Status fmi3GetVariableDependencies(fmi3Instance instance,
326  fmi3ValueReference dependent,
327  size_t elementIndicesOfDependent[],
328  fmi3ValueReference independents[],
329  size_t elementIndicesOfIndependents[],
330  fmi3DependencyKind dependencyKinds[],
331  size_t nDependencies) {
332  // Not implemented
333  return fmi3Fatal;
334 }
335 
336 FMI3_Export fmi3Status fmi3GetFMUState(fmi3Instance instance,
337  fmi3FMUState* FMUState) {
338  // Not implemented
339  return fmi3Fatal;
340 }
341 
342 FMI3_Export fmi3Status fmi3SetFMUState(fmi3Instance instance,
343  fmi3FMUState FMUState) {
344  // Not implemented
345  return fmi3Fatal;
346 }
347 
348 FMI3_Export fmi3Status fmi3FreeFMUState(fmi3Instance instance,
349  fmi3FMUState* FMUState) {
350  // Not implemented
351  return fmi3Fatal;
352 }
353 
354 FMI3_Export fmi3Status fmi3SerializedFMUStateSize(fmi3Instance instance,
355  fmi3FMUState FMUState,
356  size_t* size) {
357  // Not implemented
358  return fmi3Fatal;
359 }
360 
361 FMI3_Export fmi3Status fmi3SerializeFMUState(fmi3Instance instance,
362  fmi3FMUState FMUState,
363  fmi3Byte serializedState[],
364  size_t size) {
365  // Not implemented
366  return fmi3Fatal;
367 
368  }
369 FMI3_Export fmi3Status fmi3DeserializeFMUState(fmi3Instance instance,
370  const fmi3Byte serializedState[],
371  size_t size,
372  fmi3FMUState* FMUState) {
373  // Not implemented
374  return fmi3Fatal;
375 }
376 
377 FMI3_Export void fmi3FreeInstance(fmi3Instance instance) {
378  if (instance) {
379  // Free memory structure
380  free(instance);
381  // Decrease counters for codegen
382  MODELNAME_decref();
383 #if N_ZERO > 0
384  transition_MODELNAME_decref();
385 #endif // N_ZERO > 0
386  }
387 }
388 
389 FMI3_Export fmi3Status fmi3SetFloat64(
390  fmi3Instance instance,
391  const fmi3ValueReference valueReferences[],
392  size_t nValueReferences,
393  const fmi3Float64 values[],
394  size_t nValues) {
395  // Local variables
397  size_t i, j, var_off, var_sz, val_ind;
398  fmi3ValueReference vr;
399  // Cast to memory struct
400  m = (casadi_fmi_memory*)instance;
401  // Not evaluated
402  m->up_to_date = 0;
403  // Position in values vector
404  val_ind = 0;
405  // Loop over provided variables
406  for (i = 0; i < nValueReferences; ++i) {
407  // Get variable
408  vr = valueReferences[i];
409  // Get offset, size of variable
410  var_off = var_offset[vr];
411  var_sz = var_offset[vr + 1] - var_off;
412  // Copy elements
413  for (j = 0; j < var_sz; ++j) m->v[var_off + j] = values[val_ind++];
414  }
415  // Consistency check
416  if (val_ind != nValues) return fmi3Fatal;
417  // Successful return
418  return fmi3OK;
419 }
420 
421 FMI3_Export fmi3Status fmi3GetFloat64(
422  fmi3Instance instance,
423  const fmi3ValueReference valueReferences[],
424  size_t nValueReferences,
425  fmi3Float64 values[],
426  size_t nValues) {
427  // Local variables
429  size_t i, j, var_off, var_sz, val_ind;
430  fmi3ValueReference vr;
431  // Cast to memory struct
432  m = (casadi_fmi_memory*)instance;
433  // Evaluate, if necessary
434  if (!m->up_to_date) {
435  // Evaluate state derivatives and outputs
436  if (evaluate(m)) return fmi3Error;
437  // Now evaluated
438  m->up_to_date = 1;
439  }
440  // Position in values vector
441  val_ind = 0;
442  // Loop over provided variables
443  for (i = 0; i < nValueReferences; ++i) {
444  // Get variable
445  vr = valueReferences[i];
446  // Get offset, size of variable
447  var_off = var_offset[vr];
448  var_sz = var_offset[vr + 1] - var_off;
449  // Copy elements
450  for (j = 0; j < var_sz; ++j) values[val_ind++] = m->v[var_off + j];
451  }
452  // Consistency check
453  if (val_ind != nValues) return fmi3Fatal;
454  // Successful return
455  return fmi3OK;
456 }
457 
458 FMI3_Export fmi3Status fmi3EnterInitializationMode(
459  fmi3Instance instance,
460  fmi3Boolean toleranceDefined,
461  fmi3Float64 tolerance,
462  fmi3Float64 startTime,
463  fmi3Boolean stopTimeDefined,
464  fmi3Float64 stopTime) {
465  // Local variables
467  // Unused variables
468  (void)toleranceDefined; // unused
469  (void)tolerance; // unused
470  (void)stopTimeDefined; // unused
471  (void)stopTime; // unused
472  // Cast to memory struct
473  m = (casadi_fmi_memory*)instance;
474  // Initialize time
475  m->t = startTime;
476  // Always successful return
477  return fmi3OK;
478 }
479 
480 FMI3_Export fmi3Status fmi3ExitInitializationMode(fmi3Instance instance) {
481  // Unused variables
482  (void)instance; // unused
483  // Always successful return
484  return fmi3OK;
485 }
486 
487 FMI3_Export fmi3Status fmi3EnterContinuousTimeMode(fmi3Instance instance) {
488  // Unused variables
489  (void)instance; // unused
490  // Always successful return
491  return fmi3OK;
492 }
493 
494 FMI3_Export fmi3Status fmi3SetTime(fmi3Instance instance, fmi3Float64 time) {
495  // Local variables
497  // Cast to memory struct
498  m = (casadi_fmi_memory*)instance;
499  // Initialize time
500  m->t = time;
501  // Always successful return
502  return fmi3OK;
503 }
504 
505 FMI3_Export fmi3Status fmi3SetContinuousStates(
506  fmi3Instance instance,
507  const fmi3Float64 continuousStates[],
508  size_t nContinuousStates) {
509  return fmi3SetFloat64(instance, x_vr, N_X, continuousStates, nContinuousStates);
510 }
511 
512 FMI3_Export fmi3Status fmi3GetContinuousStates(
513  fmi3Instance instance,
514  fmi3Float64 continuousStates[],
515  size_t nContinuousStates) {
516  return fmi3GetFloat64(instance, x_vr, N_X, continuousStates, nContinuousStates);
517 }
518 
519 fmi3Status fmi3GetDirectionalDerivative(
520  fmi3Instance instance,
521  const fmi3ValueReference unknowns[],
522  size_t nUnknowns,
523  const fmi3ValueReference knowns[],
524  size_t nKnowns,
525  const fmi3Float64 seed[],
526  size_t nSeed,
527  fmi3Float64 sensitivity[],
528  size_t nSensitivity) {
529  // Local variables
531  size_t i, j, var_off, var_sz, val_ind;
532  fmi3ValueReference vr;
533  int flag;
534  // Cast to memory struct
535  m = (casadi_fmi_memory*)instance;
536  // Evaluate, if necessary
537  if (!m->up_to_date) {
538  // Evaluate state derivatives and outputs
539  if (evaluate(m)) return fmi3Error;
540  // Now evaluated
541  m->up_to_date = 1;
542  }
543  // Pass derivative seeds
544  val_ind = 0;
545  for (i = 0; i < nKnowns; ++i) {
546  // Get variable
547  vr = knowns[i];
548  // Get offset, size of variable
549  var_off = var_offset[vr];
550  var_sz = var_offset[vr + 1] - var_off;
551  // Copy elements
552  for (j = 0; j < var_sz; ++j) m->d[var_off + j] = seed[val_ind++];
553  }
554  // Consistency check
555  if (val_ind != nSeed) return fmi3Fatal;
556  // Evaluate forward directional derivatives
557  flag = evaluate_forward(m);
558  // Collect sensitivities
559  val_ind = 0;
560  for (i = 0; i < nUnknowns; ++i) {
561  // Get variable
562  vr = unknowns[i];
563  // Get offset, size of variable
564  var_off = var_offset[vr];
565  var_sz = var_offset[vr + 1] - var_off;
566  // Copy elements, clear d
567  for (j = 0; j < var_sz; ++j) {
568  sensitivity[val_ind++] = m->d[var_off + j];
569  m->d[var_off + j] = 0;
570  }
571  }
572  // Consistency check
573  if (val_ind != nSensitivity) return fmi3Fatal;
574  // Clear derivative seeds
575  val_ind = 0;
576  for (i = 0; i < nKnowns; ++i) {
577  // Get variable
578  vr = knowns[i];
579  // Get offset, size of variable
580  var_off = var_offset[vr];
581  var_sz = var_offset[vr + 1] - var_off;
582  // Clear elements
583  for (j = 0; j < var_sz; ++j) m->d[var_off + j] = 0;
584  }
585  // Check for evaluation error
586  if (flag) return fmi3Error;
587  // Successful return
588  return fmi3OK;
589 }
590 
591 fmi3Status fmi3GetAdjointDerivative(
592  fmi3Instance instance,
593  const fmi3ValueReference unknowns[],
594  size_t nUnknowns,
595  const fmi3ValueReference knowns[],
596  size_t nKnowns,
597  const fmi3Float64 seed[],
598  size_t nSeed,
599  fmi3Float64 sensitivity[],
600  size_t nSensitivity) {
601  // Local variables
603  size_t i, j, var_off, var_sz, val_ind;
604  fmi3ValueReference vr;
605  int flag;
606  // Cast to memory struct
607  m = (casadi_fmi_memory*)instance;
608  // Evaluate, if necessary
609  if (!m->up_to_date) {
610  // Evaluate state derivatives and outputs
611  if (evaluate(m)) return fmi3Error;
612  // Now evaluated
613  m->up_to_date = 1;
614  }
615  // Pass derivative seeds
616  val_ind = 0;
617  for (i = 0; i < nUnknowns; ++i) {
618  // Get variable
619  vr = unknowns[i];
620  // Get offset, size of variable
621  var_off = var_offset[vr];
622  var_sz = var_offset[vr + 1] - var_off;
623  // Copy elements
624  for (j = 0; j < var_sz; ++j) m->d[var_off + j] = seed[val_ind++];
625  }
626  // Consistency check
627  if (val_ind != nSeed) return fmi3Fatal;
628  // Evaluate adjoint directional derivatives
629  flag = evaluate_adjoint(m);
630  // Collect sensitivities
631  val_ind = 0;
632  for (i = 0; i < nKnowns; ++i) {
633  // Get variable
634  vr = knowns[i];
635  // Get offset, size of variable
636  var_off = var_offset[vr];
637  var_sz = var_offset[vr + 1] - var_off;
638  // Copy elements, clear d
639  for (j = 0; j < var_sz; ++j) {
640  sensitivity[val_ind++] = m->d[var_off + j];
641  m->d[var_off + j] = 0;
642  }
643  }
644  // Consistency check
645  if (val_ind != nSensitivity) return fmi3Fatal;
646  // Clear derivative seeds
647  val_ind = 0;
648  for (i = 0; i < nUnknowns; ++i) {
649  // Get variable
650  vr = unknowns[i];
651  // Get offset, size of variable
652  var_off = var_offset[vr];
653  var_sz = var_offset[vr + 1] - var_off;
654  // Clear elements
655  for (j = 0; j < var_sz; ++j) m->d[var_off + j] = 0;
656  }
657  // Check for evaluation error
658  if (flag) return fmi3Error;
659  // Successful return
660  return fmi3OK;
661 }
662 
663 FMI3_Export const char* fmi3GetVersion(void) {
664  return "3.0";
665 }
666 
667 FMI3_Export fmi3Status fmi3SetDebugLogging(
668  fmi3Instance instance,
669  fmi3Boolean loggingOn,
670  size_t nCategories,
671  const fmi3String categories[]) {
672  // Not implemented: Ignore for now
673  return fmi3OK;
674 }
675 
676 FMI3_Export fmi3Status fmi3Terminate(fmi3Instance instance) {
677  // No cleanup should be needed
678  return fmi3OK;
679 }
680 
681 FMI3_Export fmi3Status fmi3GetFloat32(
682  fmi3Instance instance,
683  const fmi3ValueReference valueReferences[],
684  size_t nValueReferences,
685  fmi3Float32 values[],
686  size_t nValues) {
687  // Type not implemented
688  return fmi3Fatal;
689 }
690 
691 FMI3_Export fmi3Status fmi3GetInt8(
692  fmi3Instance instance,
693  const fmi3ValueReference valueReferences[],
694  size_t nValueReferences,
695  fmi3Int8 values[],
696  size_t nValues) {
697  // Type not implemented
698  return fmi3Fatal;
699 }
700 
701 FMI3_Export fmi3Status fmi3GetUInt8(
702  fmi3Instance instance,
703  const fmi3ValueReference valueReferences[],
704  size_t nValueReferences,
705  fmi3UInt8 values[],
706  size_t nValues) {
707  // Type not implemented
708  return fmi3Fatal;
709 }
710 
711 FMI3_Export fmi3Status fmi3GetInt16(
712  fmi3Instance instance,
713  const fmi3ValueReference valueReferences[],
714  size_t nValueReferences,
715  fmi3Int16 values[],
716  size_t nValues) {
717  // Type not implemented
718  return fmi3Fatal;
719 }
720 
721 FMI3_Export fmi3Status fmi3GetUInt16(
722  fmi3Instance instance,
723  const fmi3ValueReference valueReferences[],
724  size_t nValueReferences,
725  fmi3UInt16 values[],
726  size_t nValues) {
727  // Type not implemented
728  return fmi3Fatal;
729 }
730 
731 FMI3_Export fmi3Status fmi3GetInt32(
732  fmi3Instance instance,
733  const fmi3ValueReference valueReferences[],
734  size_t nValueReferences,
735  fmi3Int32 values[],
736  size_t nValues) {
737  // Type not implemented
738  return fmi3Fatal;
739 }
740 
741 FMI3_Export fmi3Status fmi3GetUInt32(
742  fmi3Instance instance,
743  const fmi3ValueReference valueReferences[],
744  size_t nValueReferences,
745  fmi3UInt32 values[],
746  size_t nValues) {
747  // Type not implemented
748  return fmi3Fatal;
749 }
750 
751 FMI3_Export fmi3Status fmi3GetInt64(
752  fmi3Instance instance,
753  const fmi3ValueReference valueReferences[],
754  size_t nValueReferences,
755  fmi3Int64 values[],
756  size_t nValues) {
757  // Type not implemented
758  return fmi3Fatal;
759 }
760 
761 FMI3_Export fmi3Status fmi3GetUInt64(
762  fmi3Instance instance,
763  const fmi3ValueReference valueReferences[],
764  size_t nValueReferences,
765  fmi3UInt64 values[],
766  size_t nValues) {
767  // Type not implemented
768  return fmi3Fatal;
769 }
770 
771 FMI3_Export fmi3Status fmi3GetBoolean(
772  fmi3Instance instance,
773  const fmi3ValueReference valueReferences[],
774  size_t nValueReferences,
775  fmi3Boolean values[],
776  size_t nValues) {
777  // Type not implemented
778  return fmi3Fatal;
779 }
780 
781 FMI3_Export fmi3Status fmi3GetString(
782  fmi3Instance instance,
783  const fmi3ValueReference valueReferences[],
784  size_t nValueReferences,
785  fmi3String values[],
786  size_t nValues) {
787  // Type not implemented
788  return fmi3Fatal;
789 }
790 
791 FMI3_Export fmi3Status fmi3GetBinary(
792  fmi3Instance instance,
793  const fmi3ValueReference valueReferences[],
794  size_t nValueReferences,
795  size_t valueSizes[],
796  fmi3Binary values[],
797  size_t nValues) {
798  // Type not implemented
799  return fmi3Fatal;
800 }
801 
802 FMI3_Export fmi3Status fmi3GetClock(
803  fmi3Instance instance,
804  const fmi3ValueReference valueReferences[],
805  size_t nValueReferences,
806  fmi3Clock values[]) {
807  // Type not implemented
808  return fmi3Fatal;
809 }
810 
811 FMI3_Export fmi3Status fmi3SetFloat32(fmi3Instance instance,
812  const fmi3ValueReference valueReferences[],
813  size_t nValueReferences,
814  const fmi3Float32 values[],
815  size_t nValues) {
816  // Type not implemented
817  return fmi3Fatal;
818 }
819 
820 FMI3_Export fmi3Status fmi3SetInt8(fmi3Instance instance,
821  const fmi3ValueReference valueReferences[],
822  size_t nValueReferences,
823  const fmi3Int8 values[],
824  size_t nValues) {
825  // Type not implemented
826  return fmi3Fatal;
827 }
828 
829 FMI3_Export fmi3Status fmi3SetUInt8(fmi3Instance instance,
830  const fmi3ValueReference valueReferences[],
831  size_t nValueReferences,
832  const fmi3UInt8 values[],
833  size_t nValues) {
834  // Type not implemented
835  return fmi3Fatal;
836 }
837 
838 FMI3_Export fmi3Status fmi3SetInt16(fmi3Instance instance,
839  const fmi3ValueReference valueReferences[],
840  size_t nValueReferences,
841  const fmi3Int16 values[],
842  size_t nValues) {
843  // Type not implemented
844  return fmi3Fatal;
845 }
846 
847 FMI3_Export fmi3Status fmi3SetUInt16(fmi3Instance instance,
848  const fmi3ValueReference valueReferences[],
849  size_t nValueReferences,
850  const fmi3UInt16 values[],
851  size_t nValues) {
852  // Type not implemented
853  return fmi3Fatal;
854 }
855 
856 FMI3_Export fmi3Status fmi3SetInt32(fmi3Instance instance,
857  const fmi3ValueReference valueReferences[],
858  size_t nValueReferences,
859  const fmi3Int32 values[],
860  size_t nValues) {
861  // Type not implemented
862  return fmi3Fatal;
863 }
864 
865 FMI3_Export fmi3Status fmi3SetUInt32(fmi3Instance instance,
866  const fmi3ValueReference valueReferences[],
867  size_t nValueReferences,
868  const fmi3UInt32 values[],
869  size_t nValues) {
870  // Type not implemented
871  return fmi3Fatal;
872 }
873 
874 FMI3_Export fmi3Status fmi3SetInt64(fmi3Instance instance,
875  const fmi3ValueReference valueReferences[],
876  size_t nValueReferences,
877  const fmi3Int64 values[],
878  size_t nValues) {
879  // Type not implemented
880  return fmi3Fatal;
881 }
882 
883 FMI3_Export fmi3Status fmi3SetUInt64(fmi3Instance instance,
884  const fmi3ValueReference valueReferences[],
885  size_t nValueReferences,
886  const fmi3UInt64 values[],
887  size_t nValues) {
888  // Type not implemented
889  return fmi3Fatal;
890 }
891 
892 FMI3_Export fmi3Status fmi3SetBoolean(fmi3Instance instance,
893  const fmi3ValueReference valueReferences[],
894  size_t nValueReferences,
895  const fmi3Boolean values[],
896  size_t nValues) {
897  // Type not implemented
898  return fmi3Fatal;
899 }
900 
901 FMI3_Export fmi3Status fmi3SetString(fmi3Instance instance,
902  const fmi3ValueReference valueReferences[],
903  size_t nValueReferences,
904  const fmi3String values[],
905  size_t nValues) {
906  // Type not implemented
907  return fmi3Fatal;
908 }
909 
910 FMI3_Export fmi3Status fmi3SetBinary(fmi3Instance instance,
911  const fmi3ValueReference valueReferences[],
912  size_t nValueReferences,
913  const size_t valueSizes[],
914  const fmi3Binary values[],
915  size_t nValues) {
916  // Type not implemented
917  return fmi3Fatal;
918 }
919 
920 FMI3_Export fmi3Status fmi3SetClock(fmi3Instance instance,
921  const fmi3ValueReference valueReferences[],
922  size_t nValueReferences,
923  const fmi3Clock values[]) {
924  // Type not implemented
925  return fmi3Fatal;
926 }
927 
928 FMI3_Export fmi3Status fmi3SetIntervalDecimal(fmi3Instance instance,
929  const fmi3ValueReference valueReferences[],
930  size_t nValueReferences,
931  const fmi3Float64 intervals[]) {
932  // Clocks not implemented
933  return fmi3Fatal;
934 }
935 
936 FMI3_Export fmi3Status fmi3GetIntervalDecimal(fmi3Instance instance,
937  const fmi3ValueReference valueReferences[],
938  size_t nValueReferences,
939  fmi3Float64 intervals[],
940  fmi3IntervalQualifier qualifiers[]) {
941  // Clocks not implemented
942  return fmi3Fatal;
943 }
944 
945 FMI3_Export fmi3Status fmi3GetShiftDecimal(fmi3Instance instance,
946  const fmi3ValueReference valueReferences[],
947  size_t nValueReferences,
948  fmi3Float64 shifts[]) {
949  // Clocks not implemented
950  return fmi3Fatal;
951 }
952 
953 FMI3_Export fmi3Status fmi3SetShiftDecimal(fmi3Instance instance,
954  const fmi3ValueReference valueReferences[],
955  size_t nValueReferences,
956  const fmi3Float64 shifts[]) {
957  // Clocks not implemented
958  return fmi3Fatal;
959 }
960 
961 FMI3_Export fmi3Status fmi3GetNumberOfContinuousStates(fmi3Instance instance,
962  size_t* nContinuousStates) {
963  if (nContinuousStates) *nContinuousStates = N_X;
964  return fmi3OK;
965 }
966 
967 FMI3_Export fmi3Status fmi3GetNumberOfEventIndicators(fmi3Instance instance,
968  size_t* nEventIndicators) {
969  if (nEventIndicators) *nEventIndicators = N_ZERO;
970  return fmi3OK;
971 }
972 
973 FMI3_Export fmi3Status fmi3GetContinuousStateDerivatives(fmi3Instance instance,
974  fmi3Float64 derivatives[], size_t nContinuousStates) {
975  (void)nContinuousStates; // unused
976  return fmi3GetFloat64(instance, xdot_vr, N_X, derivatives, N_X);
977 }
978 
979 FMI3_Export fmi3Status fmi3GetNominalsOfContinuousStates(fmi3Instance instance,
980  fmi3Float64 nominals[], size_t nContinuousStates) {
981  // Not implemented: Assume 1 for now
982  size_t i;
983  for (i = 0; i < nContinuousStates; ++i) nominals[i] = 1;
984  return fmi3OK;
985 }
986 
987 FMI3_Export fmi3Status fmi3GetEventIndicators(fmi3Instance instance,
988  fmi3Float64 eventIndicators[],
989  size_t nEventIndicators) {
990 #if N_ZERO > 0
991  // Local variables
992  fmi3Status flag;
993  size_t i;
995  fmi3Float64 most_negative;
996  // Unused variables
997  (void)nEventIndicators; // unused
998  // Cast to memory struct
999  m = (casadi_fmi_memory*)instance;
1000  // Evaluate zero crossing functions
1001  flag = fmi3GetFloat64(instance, zero_vr, N_ZERO, eventIndicators, N_ZERO);
1002  // Find the most negative, if any, for use in events handling
1003  most_negative = 0;
1004  for (i = 0; i < N_ZERO; ++i) {
1005  if (m->triggerable[i]) {
1006  // Event has been strictly positive already, check if most negative
1007  if (eventIndicators[i] < most_negative) {
1008  most_negative = eventIndicators[i];
1009  m->zeroind = i;
1010  }
1011  } else if (eventIndicators[i] > 1e-6) {
1012  // Event has become strictly positive and is allowed to trigger events
1013  m->triggerable[i] = 1;
1014  }
1015  }
1016  // Return evaluation flag
1017  return flag;
1018 #else
1019  // No zero crossings
1020  return fmi3Fatal;
1021 #endif
1022 }
1023 
1024 FMI3_Export fmi3Status fmi3CompletedIntegratorStep(fmi3Instance instance,
1025  fmi3Boolean noSetFMUStatePriorToCurrentPoint,
1026  fmi3Boolean* enterEventMode,
1027  fmi3Boolean* terminateSimulation) {
1028  // We should not need this as there are no internal iterations
1029  return fmi3OK;
1030 }
1031 
1032 FMI3_Export fmi3Status fmi3EnterEventMode(fmi3Instance instance) {
1033 #if N_ZERO > 0
1034  // Local variables
1035  casadi_fmi_memory* m;
1036  size_t i;
1037  // Cast to memory struct
1038  m = (casadi_fmi_memory*)instance;
1039  // Quick return if no zero crossing
1040  if (m->zeroind < 0) return fmi3OK;
1041  // Call event transition function
1042  if (evaluate_transition(m)) return fmi3Error;
1043  // Mark as not evaluated
1044  m->up_to_date = 0;
1045  // Possible jump in continuous states
1047  // Reset zero crossing index
1048  m->zeroind = -1;
1049  for (i = 0; i < N_ZERO; ++i) m->triggerable[i] = 0;
1050  #endif // N_ZERO > 0
1051  // Successful return
1052  return fmi3OK;
1053 }
1054 
1055 FMI3_Export fmi3Status fmi3UpdateDiscreteStates(fmi3Instance instance,
1056  fmi3Boolean* discreteStatesNeedUpdate,
1057  fmi3Boolean* terminateSimulation,
1058  fmi3Boolean* nominalsOfContinuousStatesChanged,
1059  fmi3Boolean* valuesOfContinuousStatesChanged,
1060  fmi3Boolean* nextEventTimeDefined,
1061  fmi3Float64* nextEventTime) {
1062  // Local variables
1063  casadi_fmi_memory* m;
1064  // Cast to memory struct
1065  m = (casadi_fmi_memory*)instance;
1066  // Discrete variables not yet supported
1067  *discreteStatesNeedUpdate = fmi3False;
1068  *terminateSimulation = fmi3False;
1069  *nominalsOfContinuousStatesChanged = fmi3False;
1070  *valuesOfContinuousStatesChanged = m->continuous_states_changed ? fmi3True : fmi3False;
1071  *nextEventTimeDefined = fmi3False;
1072  // Reset marker
1074  // Successful return
1075  return fmi3OK;
1076 }
1077 
1078 FMI3_Export fmi3Status fmi3EnterConfigurationMode(fmi3Instance instance) {
1079  // Not implemented
1080  return fmi3Fatal;
1081 }
1082 
1083 FMI3_Export fmi3Status fmi3ExitConfigurationMode(fmi3Instance instance) {
1084  // Not implemented
1085  return fmi3Fatal;
1086 }
1087 
1088 FMI3_Export fmi3Status fmi3GetIntervalFraction(fmi3Instance instance,
1089  const fmi3ValueReference valueReferences[],
1090  size_t nValueReferences,
1091  fmi3UInt64 counters[],
1092  fmi3UInt64 resolutions[],
1093  fmi3IntervalQualifier qualifiers[]) {
1094  // Not implemented
1095  return fmi3Fatal;
1096 }
1097 
1098 FMI3_Export fmi3Status fmi3GetShiftFraction(fmi3Instance instance,
1099  const fmi3ValueReference valueReferences[],
1100  size_t nValueReferences,
1101  fmi3UInt64 counters[],
1102  fmi3UInt64 resolutions[]) {
1103  // Not implemented
1104  return fmi3Fatal;
1105 }
1106 
1107 FMI3_Export fmi3Status fmi3SetIntervalFraction(fmi3Instance instance,
1108  const fmi3ValueReference valueReferences[],
1109  size_t nValueReferences,
1110  const fmi3UInt64 counters[],
1111  const fmi3UInt64 resolutions[]) {
1112  // Not implemented
1113  return fmi3Fatal;
1114 }
1115 
1116 FMI3_Export fmi3Status fmi3SetShiftFraction(fmi3Instance instance,
1117  const fmi3ValueReference valueReferences[],
1118  size_t nValueReferences,
1119  const fmi3UInt64 counters[],
1120  const fmi3UInt64 resolutions[]) {
1121  // Not implemented
1122  return fmi3Fatal;
1123 }
1124 
1125 FMI3_Export fmi3Status fmi3EvaluateDiscreteStates(fmi3Instance instance) {
1126  // Not implemented
1127  return fmi3Fatal;
1128 }
1129 
1130 FMI3_Export fmi3Status fmi3EnterStepMode(fmi3Instance instance) {
1131  // Not implemented
1132  return fmi3Fatal;
1133 }
1134 
1135 FMI3_Export fmi3Status fmi3GetOutputDerivatives(fmi3Instance instance,
1136  const fmi3ValueReference valueReferences[],
1137  size_t nValueReferences,
1138  const fmi3Int32 orders[],
1139  fmi3Float64 values[],
1140  size_t nValues) {
1141  // Not implemented
1142  return fmi3Fatal;
1143 }
1144 
1145 FMI3_Export fmi3Status fmi3DoStep(fmi3Instance instance,
1146  fmi3Float64 currentCommunicationPoint,
1147  fmi3Float64 communicationStepSize,
1148  fmi3Boolean noSetFMUStatePriorToCurrentPoint,
1149  fmi3Boolean* eventHandlingNeeded,
1150  fmi3Boolean* terminateSimulation,
1151  fmi3Boolean* earlyReturn,
1152  fmi3Float64* lastSuccessfulTime) {
1153  // Not implemented
1154  return fmi3Fatal;
1155 }
1156 
1157 FMI3_Export fmi3Status fmi3ActivateModelPartition(fmi3Instance instance,
1158  fmi3ValueReference clockReference,
1159  fmi3Float64 activationTime) {
1160  // Not implemented
1161  return fmi3Fatal;
1162 }
double d[SZ_MEM]
Definition: casadi_fmu.hpp:26
double dzero[N_ZERO]
Definition: casadi_fmu.hpp:49
double p[N_P]
Definition: casadi_fmu.hpp:33
double du[N_U]
Definition: casadi_fmu.hpp:47
double u[N_U]
Definition: casadi_fmu.hpp:36
casadi_int iw[SZ_IW]
Definition: casadi_fmu.hpp:53
double x[N_X]
Definition: casadi_fmu.hpp:34
const char * instance_name
Definition: casadi_fmu.hpp:22
double dx[N_X]
Definition: casadi_fmu.hpp:45
double w[SZ_W]
Definition: casadi_fmu.hpp:54
double v[SZ_MEM]
Definition: casadi_fmu.hpp:24
double * res[SZ_RES]
Definition: casadi_fmu.hpp:52
int triggerable[N_ZERO]
Definition: casadi_fmu.hpp:42
double dy[N_Y]
Definition: casadi_fmu.hpp:48
double zero[N_ZERO]
Definition: casadi_fmu.hpp:38
int continuous_states_changed
Definition: casadi_fmu.hpp:30
double dp[N_P]
Definition: casadi_fmu.hpp:44
double xdot[N_X]
Definition: casadi_fmu.hpp:35
double y[N_Y]
Definition: casadi_fmu.hpp:37
const double * arg[SZ_ARG]
Definition: casadi_fmu.hpp:51
double dxdot[N_X]
Definition: casadi_fmu.hpp:46