forked from modelica/Reference-FMUs
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathFMI1CSSimulation.c
95 lines (61 loc) · 2.5 KB
/
FMI1CSSimulation.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
#include "FMI1.h"
#include "FMI1CSSimulation.h"
#define FMI_PATH_MAX 4096
#define CALL(f) do { status = f; if (status > FMIOK) goto TERMINATE; } while (0)
FMIStatus FMI1CSSimulate(const FMISimulationSettings* s) {
FMIStatus status = FMIOK;
FMIInstance* S = s->S;
char fmuLocation[FMI_PATH_MAX] = "";
CALL(FMIPathToURI(s->unzipdir, fmuLocation, FMI_PATH_MAX));
CALL(FMI1InstantiateSlave(S,
s->modelDescription->coSimulation->modelIdentifier, // modelIdentifier
s->modelDescription->instantiationToken, // fmuGUID
fmuLocation, // fmuLocation
"application/x-fmusim", // mimeType
0.0, // timeout
s->visible, // visible
fmi1False, // interactive
s->loggingOn // loggingOn
));
// set start values
CALL(FMIApplyStartValues(S, s));
CALL(FMIApplyInput(S, s->input, s->startTime, true, true, false));
// initialize
CALL(FMI1InitializeSlave(S, s->startTime, fmi1False, 0));
CALL(FMISample(S, s->startTime, s->initialRecorder));
for (unsigned long step = 0;; step++) {
const fmi1Real time = s->startTime + step * s->outputInterval;
CALL(FMISample(S, time, s->recorder));
CALL(FMIApplyInput(S, s->input, time, true, true, false));
if (time >= s->stopTime) {
break;
}
const FMIStatus doStepStatus = FMI1DoStep(S, time, s->outputInterval, fmi1True);
if (doStepStatus == fmi1Discard) {
fmi1Boolean terminated;
CALL(FMI1GetBooleanStatus(S, fmi1DoStepStatus, &terminated));
if (terminated) {
fmi1Real lastSuccessfulTime;
CALL(FMI1GetRealStatus(S, fmi1LastSuccessfulTime, &lastSuccessfulTime));
CALL(FMISample(S, time, s->recorder));
break;
}
} else {
CALL(doStepStatus);
}
if (s->stepFinished && !s->stepFinished(s, time)) {
break;
}
}
TERMINATE:
if (status < FMIError) {
const FMIStatus terminateStatus = FMI1TerminateSlave(S);
if (terminateStatus > status) {
status = terminateStatus;
}
}
if (status != FMIFatal) {
FMI1FreeSlaveInstance(S);
}
return status;
}