forked from modelica/Reference-FMUs
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathfmusim_fmi2_cs.c
86 lines (59 loc) · 2.28 KB
/
fmusim_fmi2_cs.c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
#include "fmusim.h"
#include "fmusim_fmi2.h"
#include "fmusim_fmi2_cs.h"
#define CALL(f) do { status = f; if (status > FMIOK) goto TERMINATE; } while (0)
FMIStatus simulateFMI2CS(
FMIInstance* S,
const FMIModelDescription* modelDescription,
const char* resourceURI,
FMIRecorder* result,
const FMUStaticInput * input,
const FMISimulationSettings * settings) {
FMIStatus status = FMIOK;
CALL(FMI2Instantiate(S,
resourceURI, // fmuResourceLocation
fmi2CoSimulation, // fmuType
modelDescription->instantiationToken, // fmuGUID
fmi2False, // visible
fmi2False // loggingOn
));
// set start values
CALL(applyStartValues(S, settings));
CALL(FMIApplyInput(S, input, settings->startTime, true, true, false));
// initialize
CALL(FMI2SetupExperiment(S, fmi2False, 0.0, settings->startTime, fmi2True, settings->stopTime));
CALL(FMI2EnterInitializationMode(S));
CALL(FMI2ExitInitializationMode(S));
for (unsigned long step = 0;; step++) {
// calculate the current time
const fmi2Real time = settings->startTime + step * settings->outputInterval;
CALL(FMISample(S, time, result));
CALL(FMIApplyInput(S, input, time, true, true, false));
if (time >= settings->stopTime) {
break;
}
// call instance s1 and check status
const FMIStatus doStepStatus = FMI2DoStep(S, time, settings->outputInterval, fmi2True);
if (doStepStatus == fmi2Discard) {
fmi2Boolean terminated;
CALL(FMI2GetBooleanStatus(S, fmi2Terminated, &terminated));
if (terminated) {
fmi2Real lastSuccessfulTime;
CALL(FMI2GetRealStatus(S, fmi2LastSuccessfulTime, &lastSuccessfulTime));
S->time = lastSuccessfulTime;
CALL(FMISample(S, time, result));
break;
}
} else {
CALL(doStepStatus);
}
}
TERMINATE:
if (status != FMIFatal) {
const FMIStatus terminateStatus = FMI2Terminate(S);
if (terminateStatus != FMIFatal) {
FMI2FreeInstance(S);
}
}
return status;
}