]> gerrit.simantics Code Review - simantics/fmil.git/blob - org.simantics.fmil.core/native/FMILibrary/Test/FMI2/fmu_dummy/fmu2_model.c
Add FMILibrary-2.0.3 to org.simantics.fmil.core\native.
[simantics/fmil.git] / org.simantics.fmil.core / native / FMILibrary / Test / FMI2 / fmu_dummy / fmu2_model.c
1 /*
2 Copyright (C) 2012 Modelon AB
3
4 This program is free software: you can redistribute it and/or modify
5 it under the terms of the BSD style license.
6
7
8 This program is distributed in the hope that it will be useful,
9 but WITHOUT ANY WARRANTY; without even the implied warranty of
10 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
11 FMILIB_License.txt file for more details.
12
13 You should have received a copy of the FMILIB_License.txt file
14 along with this program. If not, contact Modelon AB <http://www.modelon.com>.
15 */
16
17 #include <stdio.h>
18 #include <string.h>
19
20 #include <fmu_dummy/fmu2_model.h>
21
22 /* Model calculation functions */
23 static int calc_initialize(component_ptr_t comp)
24 {
25         comp->states[VAR_R_HIGHT]               = 1.0;
26         comp->states[VAR_R_HIGHT_SPEED] = 4;
27         comp->reals     [VAR_R_GRATIVY]         = -9.81;
28         comp->reals     [VAR_R_BOUNCE_CONF]     = 0.5;
29         if(comp->loggingOn) {
30                 comp->functions->logger(comp->functions->componentEnvironment, comp->instanceName, fmi2OK, "INFO", "###### Initializing component ######");
31                 comp->functions->logger(comp->functions->componentEnvironment, comp->instanceName, fmi2OK, "INFO", "Init #r%d#=%g", VAR_R_HIGHT, comp->states[VAR_R_HIGHT]);
32                 comp->functions->logger(comp->functions->componentEnvironment, comp->instanceName, fmi2OK, "INFO", "Init #r%d#=%g",VAR_R_HIGHT_SPEED, comp->states[VAR_R_HIGHT_SPEED]);
33                 comp->functions->logger(comp->functions->componentEnvironment, comp->instanceName, fmi2OK, "INFO", "Init #r%d#=%g",VAR_R_GRATIVY, comp->reals   [VAR_R_GRATIVY]);
34                 comp->functions->logger(comp->functions->componentEnvironment, comp->instanceName, fmi2OK, "INFO", "Init #r%d#=%g",VAR_R_BOUNCE_CONF, comp->reals       [VAR_R_BOUNCE_CONF]);
35 /*              comp->functions->logger(comp->functions->componentEnvironment, comp->instanceName, fmi2OK, "ERROR", "Bad reference: #r-1#");
36                 comp->functions->logger(comp->functions->componentEnvironment, comp->instanceName, fmi2OK, "ERROR", "Bad reference: #r1");
37                 comp->functions->logger(comp->functions->componentEnvironment, comp->instanceName, fmi2OK, "ERROR", "Bad reference: #t1#");
38                 comp->functions->logger(comp->functions->componentEnvironment, comp->instanceName, fmi2OK, "ERROR", "Bad reference: #r10#");*/
39         }
40         return 0;
41 }
42
43 static int calc_get_derivatives(component_ptr_t comp)
44 {
45         comp->states_der[VAR_R_HIGHT]           = comp->states[VAR_R_HIGHT_SPEED];
46         comp->states_der[VAR_R_HIGHT_SPEED] = comp->reals[VAR_R_GRATIVY];
47         return 0;
48 }
49
50 static int calc_get_event_indicators(component_ptr_t comp)
51 {       
52         fmi2Real event_tol = 1e-16;
53         comp->event_indicators[EVENT_HIGHT]             = comp->states[VAR_R_HIGHT] + (comp->states[VAR_R_HIGHT] >= 0 ? event_tol : -event_tol);
54         return 0;
55 }
56
57 static int calc_event_update(component_ptr_t comp)
58 {       
59     comp->eventInfo.newDiscreteStatesNeeded           = fmi2False;
60     comp->eventInfo.terminateSimulation               = fmi2False;
61     comp->eventInfo.nominalsOfContinuousStatesChanged = fmi2False;
62     comp->eventInfo.nextEventTimeDefined              = fmi2False;
63     comp->eventInfo.nextEventTime                     = -0.0;
64         if ((comp->states[VAR_R_HIGHT] < 0) && (comp->states[VAR_R_HIGHT_SPEED] < 0)) {
65                 comp->states[VAR_R_HIGHT_SPEED] = - comp->reals[VAR_R_BOUNCE_CONF] * comp->states[VAR_R_HIGHT_SPEED];
66                 comp->states[VAR_R_HIGHT] = 0;
67
68         comp->eventInfo.valuesOfContinuousStatesChanged = fmi2True;
69                 return 0;
70         } else {
71         comp->eventInfo.valuesOfContinuousStatesChanged = fmi2False;
72                 return 1; /* Should not call the event update */
73         }
74 }
75
76
77 /* FMI 2.0 Common Functions */
78 const char* fmi_get_version()
79 {
80         return FMI_VERSION;
81 }
82
83 fmi2Status fmi_set_debug_logging(fmi2Component c, fmi2Boolean loggingOn)
84 {
85         component_ptr_t comp = (fmi2Component)c;
86         if (comp == NULL) {
87                 return fmi2Fatal;
88         } else {
89                 comp->loggingOn = loggingOn;
90                 return fmi2OK;
91         }
92 }
93
94 fmi2Status fmi_get_real(fmi2Component c, const fmi2ValueReference vr[], size_t nvr, fmi2Real value[])
95 {
96         component_ptr_t comp = (fmi2Component)c;
97         if (comp == NULL) {
98                 return fmi2Fatal;
99         } else {
100                 size_t k;
101                 for (k = 0; k < nvr; k++) {
102                         fmi2ValueReference cvr = vr[k];
103                         if (cvr < N_STATES) {
104                                 value[k] = comp->states[cvr];
105                         } 
106                         else if(cvr == 4) {
107                                 calc_get_derivatives(comp);
108                                 value[k] = comp->states_der[1];
109                         }
110                         else {
111                                 value[k] = comp->reals[cvr];
112                         }       
113                 }
114                 return fmi2OK;
115         }
116 }
117
118 fmi2Status fmi_get_integer(fmi2Component c, const fmi2ValueReference vr[], size_t nvr, fmi2Integer value[])
119 {
120         component_ptr_t comp = (fmi2Component)c;
121         if (comp == NULL) {
122                 return fmi2Fatal;
123         } else {
124                 size_t k;
125                 for (k = 0; k < nvr; k++) {
126                         value[k] = comp->integers[vr[k]];
127                 }
128                 return fmi2OK;
129         }
130 }
131
132 fmi2Status fmi_get_boolean(fmi2Component c, const fmi2ValueReference vr[], size_t nvr, fmi2Boolean value[])
133 {
134         component_ptr_t comp = (fmi2Component)c;
135         if (comp == NULL) {
136                 return fmi2Fatal;
137         } else {
138                 size_t k;
139                 for (k = 0; k < nvr; k++) {
140                         value[k] = comp->booleans[vr[k]];
141                 }
142                 return fmi2OK;
143         }
144 }
145
146 fmi2Status fmi_get_string(fmi2Component c, const fmi2ValueReference vr[], size_t nvr, fmi2String  value[])
147 {
148         component_ptr_t comp = (fmi2Component)c;
149         if (comp == NULL) {
150                 return fmi2Fatal;
151         } else {
152                 size_t k;
153                 for (k = 0; k < nvr; k++) {
154                         value[k] = comp->strings[vr[k]];
155                 }
156                 return fmi2OK;
157         }
158 }
159
160 fmi2Status fmi_set_real(fmi2Component c, const fmi2ValueReference vr[], size_t nvr, const fmi2Real value[])
161 {
162         component_ptr_t comp = (fmi2Component)c;
163         if (comp == NULL) {
164                 return fmi2Fatal;
165         } else {
166                 size_t k;
167                 for (k = 0; k < nvr; k++) {
168                         fmi2ValueReference cvr = vr[k];
169                         if (cvr < N_STATES) {
170                                 comp->states[cvr] = value[k]; 
171                         } 
172                         else if(cvr == 4) {
173                                 comp->functions->logger(c, comp->instanceName,fmi2Warning, "WARNING", "Cannot set acceleration value (calculated)");
174                                 return fmi2Error;
175                         }
176                         else {
177                                 comp->reals[cvr] = value[k]; 
178                         }                       
179                 }
180                 return fmi2OK;
181         }
182 }
183
184 fmi2Status fmi_set_integer(fmi2Component c, const fmi2ValueReference vr[], size_t nvr, const fmi2Integer value[])
185 {
186         component_ptr_t comp = (fmi2Component)c;
187         if (comp == NULL) {
188                 return fmi2Fatal;
189         } else {
190                 size_t k;
191                 for (k = 0; k < nvr; k++) {
192                         comp->integers[vr[k]] = value[k]; 
193                 }
194                 return fmi2OK;
195         }
196 }
197
198 fmi2Status fmi_set_boolean(fmi2Component c, const fmi2ValueReference vr[], size_t nvr, const fmi2Boolean value[])
199 {
200         component_ptr_t comp = (fmi2Component)c;
201         if (comp == NULL) {
202                 return fmi2Fatal;
203         } else {
204                 size_t k;
205                 for (k = 0; k < nvr; k++) {
206                         comp->booleans[vr[k]] = value[k]; 
207                 }
208                 return fmi2OK;
209         }
210 }
211
212 fmi2Status fmi_set_string(fmi2Component c, const fmi2ValueReference vr[], size_t nvr, const fmi2String  value[])
213 {
214         component_ptr_t comp = (fmi2Component)c;
215         if (comp == NULL) {
216                 return fmi2Fatal;
217         } else {
218                 size_t k;
219                 for (k = 0; k < nvr; k++) {                     
220                         size_t len;
221                         fmi2String s_dist;
222                         fmi2String s_src = value[k];
223
224                         len = strlen((char*)s_src) + 1;
225                         s_dist = comp->functions->allocateMemory(len, sizeof(char));
226                         if (s_dist == NULL) {
227                                 return fmi2Fatal;
228                         }                       
229                         strcpy((char*)s_dist, (char*)s_src);
230                         if(comp->strings[vr[k]]) {
231                                 comp->functions->freeMemory((void*)comp->strings[vr[k]]);
232                         }
233                         comp->strings[vr[k]] = s_dist;
234                 }
235
236                 /******* Logger test *******/
237                 if(comp->loggingOn == fmi2True) {
238                         for (k = 0; k < nvr; k++) {
239                                 fmi2ValueReference cvr = vr[k];
240                                 if (cvr == VAR_S_LOGGER_TEST) {
241                                         comp->functions->logger(comp->functions->componentEnvironment, comp->instanceName, fmi2Fatal, "INFO", "%s",value[k]);
242                                 }
243                         }
244                 }
245                 /******* End of logger test *******/
246                 return fmi2OK;
247         }
248 }
249
250 /* FMI 2.0 ME Functions */
251 const char* fmi_get_model_types_platform()
252 {
253         return fmi2TypesPlatform;
254 }
255
256 /* static FILE* find_string(FILE* fp, char* str, int len) {
257
258 } */
259
260 fmi2Component fmi_instantiate(fmi2String instanceName, fmi2Type fmuType,
261   fmi2String fmuGUID, fmi2String fmuLocation,
262   const fmi2CallbackFunctions *functions, fmi2Boolean visible,
263   fmi2Boolean loggingOn)
264 {
265         component_ptr_t comp;
266         int k, p;
267
268         comp = (component_ptr_t)functions->allocateMemory(1, sizeof(component_t));
269         if (comp == NULL) {
270                 return NULL;
271         } else if (strcmp(fmuGUID, FMI_GUID) != 0) {
272                 return NULL;
273         } else {        
274                 sprintf(comp->instanceName, "%s", instanceName);
275                 sprintf(comp->GUID, "%s",fmuGUID);
276                 comp->functions         = functions;
277                 /*comp->functions->allocateMemory = functions->allocateMemory;*/
278                 
279                 comp->loggingOn         = loggingOn;
280
281                 /* Set default values */
282                 for (k = 0; k < N_STATES;                       k++) comp->states[k]                    = 0.0;
283                 for (k = 0; k < N_STATES;                       k++) comp->states_prev[k]               = 0.0; /* Used in CS only */
284                 for (k = 0; k < N_STATES;                       k++) comp->states_nom[k]                = 1.0;
285                 for (k = 0; k < N_STATES;                       k++) comp->states_der[k]                = 0.0;
286                 for (k = 0; k < N_EVENT_INDICATORS; k++) comp->event_indicators[k]      = 1e10;
287                 for (k = 0; k < N_REAL;                         k++) comp->reals[k]                             = 0.0;
288                 for (k = 0; k < N_INTEGER;                      k++) comp->integers[k]                  = 0;
289                 for (k = 0; k < N_BOOLEAN;                      k++) comp->booleans[k]                  = fmi2False;
290                 for (k = 0; k < N_STRING;                       k++) comp->strings[k]                   = NULL;
291
292                 /* Used in CS only */
293                 for (k = 0; k < N_INPUT_REAL; k++) {
294                         for (p = 0; p < N_INPUT_REAL_MAX_ORDER + 1; p++) {
295                                 comp->input_real[k][p] = 0.0;
296                         }
297                 }
298
299                 /* Used in CS only */
300                 for (k = 0; k < N_OUTPUT_REAL; k++) {
301                         for (p = 0; p < N_OUTPUT_REAL_MAX_ORDER + 1; p++) {
302                                 comp->output_real[k][p] = MAGIC_TEST_VALUE;
303                         }
304                 }
305         
306                 sprintf(comp->fmuLocation, "%s",fmuLocation);
307                 comp->visible           = visible;
308                 return comp;
309         }
310 }
311
312 void fmi_free_instance(fmi2Component c)
313 {
314         int i;
315         component_ptr_t comp = (fmi2Component)c;
316         for(i = 0; i < N_STRING; i++) {
317                 comp->functions->freeMemory((void*)(comp->strings[i]));
318                 comp->strings[i] = 0;
319         }
320         comp->functions->freeMemory(c);
321 }
322
323 fmi2Status fmi_setup_experiment(fmi2Component c, fmi2Boolean toleranceDefined,
324                                fmi2Real tolerance, fmi2Real startTime,
325                                fmi2Boolean stopTimeDefined,
326                                fmi2Real stopTime)
327 {
328     component_ptr_t comp = (fmi2Component)c;
329
330     if (comp == NULL) {
331         return fmi2Fatal;
332     } else {
333         comp->toleranceControlled = toleranceDefined;
334         comp->relativeTolerance = tolerance;
335
336         comp->tStart = startTime;
337         comp->StopTimeDefined = stopTimeDefined;
338         comp->tStop = stopTime;
339
340         return fmi2OK;
341     }
342 }
343
344 fmi2Status fmi_enter_initialization_mode(fmi2Component c)
345 {
346     if (c == NULL) {
347         return fmi2Fatal;
348     } else {
349         calc_initialize(c);
350         return fmi2OK;
351     }
352 }
353
354 fmi2Status fmi_exit_initialization_mode(fmi2Component c)
355 {
356     return fmi2OK;
357 }
358
359 fmi2Status fmi_enter_event_mode(fmi2Component c)
360 {
361     return fmi2OK;
362 }
363
364 fmi2Status fmi_new_discrete_states(fmi2Component c, fmi2EventInfo* eventInfo)
365 {
366         component_ptr_t comp = (fmi2Component)c;
367         if (comp == NULL) {
368                 return fmi2Fatal;
369         } else {
370                 calc_event_update(comp);
371
372                 *eventInfo = comp->eventInfo;
373                 return fmi2OK;
374         }
375 }
376
377 fmi2Status fmi_enter_continuous_time_mode(fmi2Component c)
378 {
379     return fmi2OK;
380 }
381
382 fmi2Status fmi_set_time(fmi2Component c, fmi2Real fmitime)
383 {
384         component_ptr_t comp = (fmi2Component)c;
385         if (comp == NULL) {
386                 return fmi2Fatal;
387         } else {
388                 comp->fmitime = fmitime;
389                 return fmi2OK;
390         }
391 }
392
393 fmi2Status fmi_set_continuous_states(fmi2Component c, const fmi2Real x[], size_t nx)
394 {
395         component_ptr_t comp = (fmi2Component)c;
396         if (comp == NULL) {
397                 return fmi2Fatal;
398         } else {
399                 size_t k;
400                 for (k = 0; k < nx; k++) {
401                         comp->states[k] = x[k];
402                 }
403                 return fmi2OK;
404         }
405 }
406
407 fmi2Status fmi_completed_integrator_step(fmi2Component c,
408   fmi2Boolean noSetFMUStatePriorToCurrentPoint,
409   fmi2Boolean* enterEventMode, fmi2Boolean* terminateSimulation)
410 {
411         component_ptr_t comp = (fmi2Component)c;
412         if (comp == NULL) {
413                 return fmi2Fatal;
414         } else {
415                 *enterEventMode = fmi2False;
416                 return fmi2OK;
417         }
418 }
419
420 fmi2Status fmi_get_derivatives(fmi2Component c, fmi2Real derivatives[] , size_t nx)
421 {
422         component_ptr_t comp = (fmi2Component)c;
423         if (comp == NULL) {
424                 return fmi2Fatal;
425         } else {
426                 size_t k;
427
428                 calc_get_derivatives(comp);
429
430                 for (k = 0; k < nx; k++) {
431                         derivatives[k] = comp->states_der[k];
432                 }
433                 return fmi2OK;
434         }
435 }
436
437 fmi2Status fmi_get_event_indicators(fmi2Component c, fmi2Real eventIndicators[], size_t ni)
438 {
439         component_ptr_t comp = (fmi2Component)c;
440         if (comp == NULL) {
441                 return fmi2Fatal;
442         } else {
443                 size_t k;
444
445                 calc_get_event_indicators(comp);
446
447                 for (k = 0; k < ni; k++) {
448                         eventIndicators[k] = comp->event_indicators[k];
449                 }
450                 return fmi2OK;
451         }
452 }
453
454 fmi2Status fmi_get_continuous_states(fmi2Component c, fmi2Real states[], size_t nx)
455 {
456         component_ptr_t comp = (fmi2Component)c;
457         if (comp == NULL) {
458                 return fmi2Fatal;
459         } else {
460                 size_t k;
461
462                 for (k = 0; k < nx; k++) {
463                         states[k] = comp->states[k];
464                 }
465                 return fmi2OK;
466         }
467 }
468
469 fmi2Status fmi_get_nominals_of_continuousstates(fmi2Component c, fmi2Real x_nominal[], size_t nx)
470 {
471         component_ptr_t comp = (fmi2Component)c;
472         if (comp == NULL) {
473                 return fmi2Fatal;
474         } else {
475                 size_t k;
476                 for (k = 0; k < nx; k++) {
477                         x_nominal[k] = comp->states_nom[k];
478                 }
479                 return fmi2OK;
480         }
481 }
482
483 fmi2Status fmi_terminate(fmi2Component c)
484 {
485         component_ptr_t comp = (fmi2Component)c;
486         if (comp == NULL) {
487                 return fmi2Fatal;
488         } else {
489                 return fmi2OK;
490         }
491 }
492
493 /* FMI 2.0 CS Functions */
494 const char* fmi_get_types_platform()
495 {
496         return fmi2TypesPlatform;
497 }
498
499 fmi2Status fmi_reset(fmi2Component c)
500 {
501         return fmi2OK;
502 }
503
504 fmi2Status fmi_set_real_input_derivatives(fmi2Component c, const fmi2ValueReference vr[], size_t nvr, const fmi2Integer order[], const fmi2Real value[])
505 {
506
507         component_ptr_t comp    = (fmi2Component)c;
508         size_t k;
509
510         for (k = 0; k < nvr; k++) {
511                 comp->input_real[vr[k]][order[k]] = value[k];
512                 if (value[k] != MAGIC_TEST_VALUE) {/* Tests that the value is set to MAGIC_TEST_VALUE */
513                         return fmi2Fatal;
514                 }
515         }
516
517         return fmi2OK;
518 }
519
520 fmi2Status fmi_get_real_output_derivatives(fmi2Component c, const fmi2ValueReference vr[], size_t nvr, const fmi2Integer order[], fmi2Real value[])
521 {
522         component_ptr_t comp    = (fmi2Component)c;
523         size_t k;
524
525         for (k = 0; k < nvr; k++) {
526                 value[k] = comp->output_real[vr[k]][order[k]];
527         }
528
529         return fmi2OK;
530 }
531
532 fmi2Status fmi_cancel_step(fmi2Component c)
533 {
534         return fmi2OK;
535 }
536
537 fmi2Status fmi_do_step(fmi2Component c, fmi2Real currentCommunicationPoint, fmi2Real communicationStepSize, fmi2Boolean newStep)
538 {
539         component_ptr_t comp    = (fmi2Component)c;
540
541         if (comp == NULL) {
542                 return fmi2Fatal;
543         } else {
544                 fmi2Real tstart = currentCommunicationPoint;
545                 fmi2Real tcur;
546                 fmi2Real tend = currentCommunicationPoint + communicationStepSize;
547                 fmi2Real hcur; 
548                 fmi2Real hdef = 0.01;   /* Default time step length */
549                 fmi2Real z_cur[N_EVENT_INDICATORS];
550                 fmi2Real z_pre[N_EVENT_INDICATORS];
551                 fmi2Real states[N_STATES];
552                 fmi2Real states_der[N_STATES];
553                 fmi2EventInfo eventInfo;
554                 fmi2Boolean callEventUpdate;
555                 fmi2Boolean terminateSimulation;
556                 fmi2Status fmi2Status;  
557                 size_t k;
558                 size_t counter = 0;
559
560                 fmi_get_continuous_states(comp, states, N_STATES);
561                 fmi_get_event_indicators(comp, z_pre, N_EVENT_INDICATORS);
562
563                 tcur = tstart;
564                 hcur = hdef;
565                 callEventUpdate = fmi2False;
566                 eventInfo = comp->eventInfo;
567
568                 while (tcur < tend && counter < 100) {
569                         size_t k;
570                         int zero_crossning_event = 0;
571                         counter++;
572
573                         fmi_set_time(comp, tcur);
574                         fmi_get_event_indicators(comp, z_cur, N_EVENT_INDICATORS);
575
576                         /* Check if an event inidcator has triggered */
577                         for (k = 0; k < N_EVENT_INDICATORS; k++) {
578                                 if (z_cur[k]*z_pre[k] < 0) {
579                                         zero_crossning_event = 1;
580                                         break;
581                                 }
582                         }
583
584                         /* Handle any events */
585                         if (callEventUpdate || zero_crossning_event ||
586                           (eventInfo.nextEventTimeDefined && tcur == eventInfo.nextEventTime)) {
587                                 fmi2Status = fmi_new_discrete_states(comp, &eventInfo);
588                                 fmi2Status = fmi_get_continuous_states(comp, states, N_STATES);
589                                 fmi2Status = fmi_get_event_indicators(comp, z_cur, N_EVENT_INDICATORS);
590                                 fmi2Status = fmi_get_event_indicators(comp, z_pre, N_EVENT_INDICATORS);
591                         }
592
593                         /* Updated next time step */
594                         if (eventInfo.nextEventTimeDefined) {
595                                 if (tcur + hdef < eventInfo.nextEventTime) {
596                                         hcur = hdef;
597                                 } else {
598                                         hcur = eventInfo.nextEventTime - tcur;
599                                 }
600                         } else {
601                                 hcur = hdef;
602                         }
603
604                         { 
605                                 double t_full = tcur + hcur;
606                                 if(t_full > tend) {
607                                         hcur = (tend - tcur);
608                                         tcur = tend;                            
609                                 }
610                                 else
611                                         tcur = t_full;
612                         }
613
614                         /* Integrate a step */
615                         fmi2Status = fmi_get_derivatives(comp, states_der, N_STATES);
616                         for (k = 0; k < N_STATES; k++) {
617                                 states[k] = states[k] + hcur*states_der[k];     
618                                 /* if (k == 0) printf("states[%u] = %f states_der[k] = %f hcur =%f\n", k, states[k], states_der[k], hcur); */
619                         }
620
621                         /* Set states */
622                         fmi2Status = fmi_set_continuous_states(comp, states, N_STATES);
623                         /* Step is complete */
624                         fmi2Status = fmi_completed_integrator_step(comp, fmi2True,
625                             &callEventUpdate, &terminateSimulation);
626             
627             if(fmi2Status != fmi2OK) break;
628
629                 }
630                 for (k = 0; k < N_STATES; k++) { /* Update states */
631                         comp->reals[k] = comp->states[k];
632                 }
633                 return fmi2OK;
634         }
635 }
636
637 fmi2Status fmi_get_status(fmi2Component c, const fmi2StatusKind s, fmi2Status*  value)
638 {
639         switch (s) {
640                 case fmi2DoStepStatus:
641                         /* Return fmiPending if we are waiting. Otherwise the result from fmiDoStep */
642                         *value = fmi2OK;
643                         return fmi2OK;
644                 default: /* Not defined for status for this function */
645                         return fmi2Discard;
646         }
647 }
648
649 fmi2Status fmi_get_real_status(fmi2Component c, const fmi2StatusKind s, fmi2Real*    value)
650 {
651         switch (s) {
652                 case fmi2LastSuccessfulTime:
653                         /* Return fmiPending if we are waiting. Otherwise return end time for last call to fmiDoStep */
654                         *value = 0.01;
655                         return fmi2OK;
656                 default: /* Not defined for status for this function */
657                         return fmi2Discard;
658         }
659 }
660
661 fmi2Status fmi_get_integer_status(fmi2Component c, const fmi2StatusKind s, fmi2Integer* value)
662 {
663         switch (s) {
664                 default: /* Not defined for status for this function */
665                         return fmi2Discard;
666         }
667 }
668
669 fmi2Status fmi_get_boolean_status(fmi2Component c, const fmi2StatusKind s, fmi2Boolean* value)
670 {
671         switch (s) {
672                 default: /* Not defined for status for this function */
673                         return fmi2Discard;
674         }
675 }
676
677 fmi2Status fmi_get_string_status(fmi2Component c, const fmi2StatusKind s, fmi2String*  value)
678 {
679         switch (s) {
680                 case fmi2PendingStatus:
681                         *value = "Did fmi2DoStep really return with fmi2Pending? Then its time to implement this function";
682                         return fmi2Discard;
683                 default: /* Not defined for status for this function */
684                         return fmi2Discard;
685         }
686 }