-
Notifications
You must be signed in to change notification settings - Fork 60
/
FMI2CSSimulation.c
108 lines (73 loc) · 2.64 KB
/
FMI2CSSimulation.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
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
#include "FMIUtil.h"
#include "FMI2.h"
#include "FMI2CSSimulation.h"
#define FMI_PATH_MAX 4096
#define CALL(f) do { status = f; if (status > FMIOK) goto TERMINATE; } while (0)
FMIStatus FMI2CSSimulate(const FMISimulationSettings* s) {
FMIStatus status = FMIOK;
char resourcePath[FMI_PATH_MAX] = "";
char resourceURI[FMI_PATH_MAX] = "";
#ifdef _WIN32
snprintf(resourcePath, FMI_PATH_MAX, "%s\\resources\\", s->unzipdir);
#else
snprintf(resourcePath, FMI_PATH_MAX, "%s/resources/", s->unzipdir);
#endif
CALL(FMIPathToURI(resourcePath, resourceURI, FMI_PATH_MAX));
FMIInstance* S = s->S;
CALL(FMI2Instantiate(S,
resourceURI,
fmi2CoSimulation,
s->modelDescription->instantiationToken,
s->visible,
s->loggingOn
));
if (s->initialFMUStateFile) {
CALL(FMIRestoreFMUStateFromFile(S, s->initialFMUStateFile));
}
CALL(FMIApplyStartValues(S, s));
if (!s->initialFMUStateFile) {
CALL(FMI2SetupExperiment(S, s->tolerance > 0, s->tolerance, s->startTime, fmi2False, 0));
CALL(FMI2EnterInitializationMode(S));
CALL(FMIApplyInput(S, s->input, s->startTime, true, true, true));
CALL(FMI2ExitInitializationMode(S));
}
CALL(FMISample(S, s->startTime, s->initialRecorder));
for (unsigned long step = 0;; step++) {
const fmi2Real time = s->startTime + step * s->outputInterval;
CALL(FMISample(S, time, s->recorder));
if (time > s->stopTime || FMIIsClose(time, s->stopTime)) {
break;
}
CALL(FMIApplyInput(S, s->input, time, true, true, true));
const FMIStatus doStepStatus = FMI2DoStep(S, time, s->outputInterval, fmi2True);
if (doStepStatus == fmi2Discard) {
fmi2Boolean terminated;
CALL(FMI2GetBooleanStatus(S, fmi2Terminated, &terminated));
if (terminated) {
fmi2Real lastSuccessfulTime;
CALL(FMI2GetRealStatus(S, fmi2LastSuccessfulTime, &lastSuccessfulTime));
CALL(FMISample(S, lastSuccessfulTime, s->recorder));
break;
}
} else {
CALL(doStepStatus);
}
if (s->stepFinished && !s->stepFinished(s, time)) {
break;
}
}
if (s->finalFMUStateFile) {
CALL(FMISaveFMUStateToFile(S, s->finalFMUStateFile));
}
TERMINATE:
if (status < FMIError) {
const FMIStatus terminateStatus = FMI2Terminate(S);
if (terminateStatus > status) {
status = terminateStatus;
}
}
if (status != FMIFatal) {
FMI2FreeInstance(S);
}
return status;
}