Skip to content

Commit ae251d9

Browse files
committed
Merge branch 'master' into examples
2 parents dcdb556 + af9dd86 commit ae251d9

5 files changed

Lines changed: 146 additions & 9 deletions

File tree

export/src/fmu4cpp/fmi2/fmi2.cpp

Lines changed: 61 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11

22
#include "fmi2Functions.h"
33

4+
#include <cstring>
45
#include <fstream>
56
#include <limits>
67
#include <memory>
@@ -473,6 +474,7 @@ fmi2Status fmi2GetDirectionalDerivative(fmi2Component,
473474

474475

475476
fmi2Status fmi2GetFMUstate(fmi2Component c, fmi2FMUstate *state) {
477+
476478
const auto component = static_cast<Fmi2Component *>(c);
477479

478480
try {
@@ -491,6 +493,7 @@ fmi2Status fmi2GetFMUstate(fmi2Component c, fmi2FMUstate *state) {
491493
}
492494

493495
fmi2Status fmi2SetFMUstate(fmi2Component c, fmi2FMUstate state) {
496+
494497
const auto component = static_cast<Fmi2Component *>(c);
495498

496499
try {
@@ -509,6 +512,11 @@ fmi2Status fmi2SetFMUstate(fmi2Component c, fmi2FMUstate state) {
509512

510513

511514
fmi2Status fmi2FreeFMUstate(fmi2Component c, fmi2FMUstate *state) {
515+
516+
if (state == nullptr || *state == nullptr) {
517+
return fmi2OK;
518+
}
519+
512520
const auto component = static_cast<Fmi2Component *>(c);
513521

514522
try {
@@ -525,23 +533,68 @@ fmi2Status fmi2FreeFMUstate(fmi2Component c, fmi2FMUstate *state) {
525533
}
526534
}
527535

528-
fmi2Status fmi2SerializedFMUstateSize(fmi2Component, fmi2FMUstate, size_t *) {
536+
fmi2Status fmi2SerializedFMUstateSize(fmi2Component c, fmi2FMUstate state, size_t *size) {
529537

530-
return fmi2Error;
538+
const auto component = static_cast<Fmi2Component *>(c);
539+
540+
try {
541+
542+
component->slave->serializedFMUStateSize(state, *size);
543+
return fmi2OK;
544+
545+
} catch (const fmu4cpp::fatal_error &ex) {
546+
component->logger->log(fmiFatal, ex.what());
547+
return fmi2Fatal;
548+
} catch (const std::exception &ex) {
549+
component->logger->log(fmiError, ex.what());
550+
return fmi2Error;
551+
}
531552
}
532553

533-
fmi2Status fmi2SerializeFMUstate(fmi2Component, fmi2FMUstate, fmi2Byte[], size_t) {
554+
fmi2Status fmi2SerializeFMUstate(fmi2Component c, fmi2FMUstate state, fmi2Byte data[], size_t size) {
534555

535-
return fmi2Error;
556+
const auto component = static_cast<Fmi2Component *>(c);
557+
558+
try {
559+
560+
std::vector<uint8_t> serializedState(size);
561+
component->slave->serializeFMUState(state, serializedState);
562+
std::memcpy(data, serializedState.data(), size);
563+
return fmi2OK;
564+
565+
} catch (const fmu4cpp::fatal_error &ex) {
566+
component->logger->log(fmiFatal, ex.what());
567+
return fmi2Fatal;
568+
} catch (const std::exception &ex) {
569+
component->logger->log(fmiError, ex.what());
570+
return fmi2Error;
571+
}
536572
}
537573

538-
fmi2Status fmi2DeSerializeFMUstate(fmi2Component, const fmi2Byte[], size_t, fmi2FMUstate *) {
574+
fmi2Status fmi2DeSerializeFMUstate(fmi2Component c, const fmi2Byte data[], size_t size, fmi2FMUstate *state) {
539575

540-
return fmi2Error;
576+
const auto component = static_cast<Fmi2Component *>(c);
577+
578+
try {
579+
580+
std::vector<uint8_t> serializedState(data, data + size);
581+
component->slave->deserializeFMUState(serializedState, state);
582+
return fmi2OK;
583+
584+
} catch (const fmu4cpp::fatal_error &ex) {
585+
component->logger->log(fmiFatal, ex.what());
586+
return fmi2Fatal;
587+
} catch (const std::exception &ex) {
588+
component->logger->log(fmiError, ex.what());
589+
return fmi2Error;
590+
}
541591
}
542592

543593
void fmi2FreeInstance(fmi2Component c) {
544-
const auto component = static_cast<Fmi2Component *>(c);
545-
delete component;
594+
if (c) {
595+
const auto component = static_cast<Fmi2Component *>(c);
596+
delete component;
597+
c = nullptr;
598+
}
546599
}
547600
}

export/src/fmu4cpp/fmi3/fmi3.cpp

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -641,6 +641,11 @@ fmi3Status fmi3SetFMUState(fmi3Instance c, fmi3FMUState state) {
641641

642642

643643
fmi3Status fmi3FreeFMUState(fmi3Instance c, fmi3FMUState *state) {
644+
645+
if (state == nullptr || *state == nullptr) {
646+
return fmi3OK;
647+
}
648+
644649
const auto component = static_cast<Fmi3Component *>(c);
645650

646651
try {
@@ -660,6 +665,7 @@ fmi3Status fmi3FreeFMUState(fmi3Instance c, fmi3FMUState *state) {
660665
}
661666

662667
fmi3Status fmi3SerializedFMUStateSize(fmi3Instance c, fmi3FMUState state, size_t *size) {
668+
663669
const auto component = static_cast<Fmi3Component *>(c);
664670

665671
try {
@@ -939,6 +945,7 @@ void fmi3FreeInstance(fmi3Instance c) {
939945
const auto component = static_cast<Fmi3Component *>(c);
940946
component->state = Fmi3Component::State::Invalid;
941947
delete component;
948+
c = nullptr;
942949
}
943950
}
944951
}

export/tests/fmi2/CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
11

22
make_test("fmi2" array_test array_test.cpp)
33
make_test("fmi2" identity_test identity_test.cpp)
4+
make_test("fmi2" bouncing_ball_test bouncing_ball_test.cpp)
Lines changed: 75 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,75 @@
1+
2+
#include <catch2/catch_approx.hpp>
3+
#include <catch2/catch_test_macros.hpp>
4+
5+
#include "fmi2/fmi2Functions.h"
6+
7+
#include "BouncingBall.hpp"
8+
9+
10+
std::string fmu4cpp::model_identifier() {
11+
return "bouncing_ball";
12+
}
13+
14+
15+
TEST_CASE("BouncingBall_test") {
16+
17+
BouncingBall model({});
18+
const auto guid = model.guid();
19+
20+
auto c = fmi2Instantiate("bouncing_ball", fmi2CoSimulation, guid.c_str(), "", nullptr, false, false);
21+
REQUIRE(c);
22+
23+
REQUIRE(fmi2SetupExperiment(c, fmi2False, 0, 0, fmi2False, 0) == fmi2OK);
24+
REQUIRE(fmi2EnterInitializationMode(c) == fmi2OK);
25+
REQUIRE(fmi2ExitInitializationMode(c) == fmi2OK);
26+
27+
double t = 0;
28+
double dt = 0.1;
29+
30+
REQUIRE(fmi2DoStep(c, t, dt, true) == fmi2OK);
31+
t += dt;
32+
33+
const auto heightVr = model.get_real_variable("height")->value_reference();
34+
35+
double height;
36+
REQUIRE(fmi2GetReal(c, &heightVr, 1, &height) == fmi2OK);
37+
REQUIRE(height < 10.0);
38+
39+
double heightState = height;
40+
41+
fmi2FMUstate state;
42+
REQUIRE(fmi2GetFMUstate(c, &state) == fmi2OK);
43+
44+
REQUIRE(fmi2DoStep(c, t, dt, true) == fmi2OK);
45+
t += dt;
46+
47+
REQUIRE(fmi2GetReal(c, &heightVr, 1, &height) == fmi2OK);
48+
CHECK(height != Catch::Approx(heightState));
49+
50+
REQUIRE(fmi2SetFMUstate(c, state) == fmi2OK);
51+
REQUIRE(fmi2GetReal(c, &heightVr, 1, &height) == fmi2OK);
52+
CHECK(height == Catch::Approx(heightState));
53+
54+
55+
size_t serializedSize;
56+
fmi2SerializedFMUstateSize(c, state, &serializedSize);
57+
CHECK(serializedSize > 0);
58+
59+
std::vector<char> serializedData(serializedSize);
60+
fmi2SerializeFMUstate(c, state, serializedData.data(), serializedSize);
61+
fmi2DeSerializeFMUstate(c, serializedData.data(), serializedSize, &state);
62+
63+
REQUIRE(fmi2DoStep(c, t, dt, true) == fmi2OK);
64+
65+
REQUIRE(fmi2GetReal(c, &heightVr, 1, &height) == fmi2OK);
66+
CHECK(height != Catch::Approx(heightState));
67+
68+
REQUIRE(fmi2SetFMUstate(c, state) == fmi2OK);
69+
REQUIRE(fmi2GetReal(c, &heightVr, 1, &height) == fmi2OK);
70+
CHECK(height == Catch::Approx(heightState));
71+
72+
73+
REQUIRE(fmi2FreeFMUstate(c, &state) == fmi2OK);
74+
REQUIRE(state == nullptr);
75+
}

export/tests/fmi3/bouncing_ball_test.cpp

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ TEST_CASE("BouncingBall_test") {
1717
BouncingBall model({});
1818
const auto guid = model.guid();
1919

20-
auto c = fmi3InstantiateCoSimulation("array", guid.c_str(), "", false, false, false, false, nullptr, 0, nullptr, nullptr, nullptr);
20+
auto c = fmi3InstantiateCoSimulation("bouncing_ball", guid.c_str(), "", false, false, false, false, nullptr, 0, nullptr, nullptr, nullptr);
2121
REQUIRE(c);
2222

2323
REQUIRE(fmi3EnterInitializationMode(c, false, 0, 0, false, 0) == fmi3OK);
@@ -74,4 +74,5 @@ TEST_CASE("BouncingBall_test") {
7474

7575

7676
REQUIRE(fmi3FreeFMUState(c, &state) == fmi3OK);
77+
REQUIRE(state == nullptr);
7778
}

0 commit comments

Comments
 (0)