Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 10 additions & 0 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -39,4 +39,14 @@ if(NOT CPPFMU_FMI_1)
target_compile_features(cs_test PRIVATE cxx_std_11)
target_link_libraries(cs_test PRIVATE cppfmu)
add_test(NAME "cs_test" COMMAND cs_test)
else()
add_executable(cs_test_fmi1
"tests/cs_test.cpp"
"tests/cs_slave.cpp"
"fmi_functions.cpp"
)
target_compile_features(cs_test_fmi1 PRIVATE cxx_std_11)
target_link_libraries(cs_test_fmi1 PRIVATE cppfmu)
target_compile_definitions(cs_test_fmi1 PRIVATE CPPFMU_USE_FMI_1_0 "MODEL_IDENTIFIER=")
add_test(NAME "cs_test_fmi1" COMMAND cs_test_fmi1)
endif()
2 changes: 1 addition & 1 deletion conanfile.py
Original file line number Diff line number Diff line change
Expand Up @@ -98,7 +98,7 @@ def build(self):
cmake = CMake(self)
cmake.configure()
cmake.build()
cmake.ctest("--output-on-failure")
cmake.ctest(cli_args=["--output-on-failure"])

def package(self):
copy(self, "LICENCE.txt", self.source_folder,
Expand Down
32 changes: 32 additions & 0 deletions cppfmu_cs.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -139,6 +139,38 @@ void SlaveInstance::GetString(
}


void SlaveInstance::GetDirectionalDerivative(
const FMIValueReference /*vUnknown_ref*/[],
std::size_t /*nUnknown*/,
const FMIValueReference /*vKnown_ref*/[],
std::size_t /*nKnown*/,
const FMIReal /*dvKnown*/[],
FMIReal /*dvUnknown*/[]) const
{
throw std::logic_error("Operation not supported: get directional derivative");
}


void SlaveInstance::SetRealInputDerivatives(
const FMIValueReference /*vr*/[],
std::size_t /*nvr*/,
const FMIInteger /*order*/[],
const FMIReal /*value*/[])
{
throw std::logic_error("Operation not supported: set real input derivatives");
}


void SlaveInstance::GetRealOutputDerivatives(
const FMIValueReference /*vr*/[],
std::size_t /*nvr*/,
const FMIInteger /*order*/[],
FMIReal /*value*/[]) const
{
throw std::logic_error("Operation not supported: get real output derivatives");
}


void SlaveInstance::GetFMUState(FMIFMUState* state)
{
throw std::logic_error("Operation not supported: get FMU state");
Expand Down
29 changes: 29 additions & 0 deletions cppfmu_cs.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -103,6 +103,35 @@ class SlaveInstance
std::size_t nvr,
FMIString value[]) const;

/* Called from fmi2GetDirectionalDerivative()/fmiGetDirectionalDerivative().
* Throws std::logic_error by default.
*/
virtual void GetDirectionalDerivative(
const FMIValueReference vUnknown_ref[],
std::size_t nUnknown,
const FMIValueReference vKnown_ref[],
std::size_t nKnown,
const FMIReal dvKnown[],
FMIReal dvUnknown[]) const;

/* Called from fmi2SetRealInputDerivatives()/fmiSetRealInputDerivatives().
* Throws std::logic_error by default.
*/
virtual void SetRealInputDerivatives(
const FMIValueReference vr[],
std::size_t nvr,
const FMIInteger order[],
const FMIReal value[]);

/* Called from fmi2GetRealOutputDerivatives()/fmiGetRealOutputDerivatives().
* Throws std::logic_error by default.
*/
virtual void GetRealOutputDerivatives(
const FMIValueReference vr[],
std::size_t nvr,
const FMIInteger order[],
FMIReal value[]) const;

/* Called from fmi2GetFMUState().
* Never called with FMI 1.x.
* Throws std::logic_error by default.
Expand Down
128 changes: 81 additions & 47 deletions fmi_functions.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -318,33 +318,46 @@ fmiStatus fmiSetString (fmiComponent c, const fmiValueReference vr[], size_t nv
}



fmiStatus fmiSetRealInputDerivatives(
fmiComponent c,
const fmiValueReference /*vr*/[],
size_t /*nvr*/,
const fmiInteger /*order*/[],
const fmiReal /*value*/[])
const fmiValueReference vr[],
size_t nvr,
const fmiInteger order[],
const fmiReal value[])
{
reinterpret_cast<Component*>(c)->logger.Log(
fmiError,
"cppfmu",
"FMI function not supported: fmiSetRealInputDerivatives");
return fmiError;
const auto component = reinterpret_cast<Component*>(c);
try {
component->slave->SetRealInputDerivatives(vr, nvr, order, value);
return fmiOK;
} catch (const cppfmu::FatalError& e) {
component->logger.Log(fmiFatal, "", e.what());
return fmiFatal;
} catch (const std::exception& e) {
component->logger.Log(fmiError, "", e.what());
return fmiError;
}
}


fmiStatus fmiGetRealOutputDerivatives(
fmiComponent c,
const fmiValueReference /*vr*/[],
size_t /*nvr*/,
const fmiInteger /*order*/[],
fmiReal /*value*/[])
const fmiValueReference vr[],
size_t nvr,
const fmiInteger order[],
fmiReal value[])
{
reinterpret_cast<Component*>(c)->logger.Log(
fmiError,
"cppfmu",
"FMI function not supported: fmiGetRealOutputDerivatives");
return fmiError;
const auto component = reinterpret_cast<Component*>(c);
try {
component->slave->GetRealOutputDerivatives(vr, nvr, order, value);
return fmiOK;
} catch (const cppfmu::FatalError& e) {
component->logger.Log(fmiFatal, "", e.what());
return fmiFatal;
} catch (const std::exception& e) {
component->logger.Log(fmiError, "", e.what());
return fmiError;
}
}


Expand Down Expand Up @@ -908,46 +921,67 @@ fmi2Status fmi2DeSerializeFMUstate(

fmi2Status fmi2GetDirectionalDerivative(
fmi2Component c,
const fmi2ValueReference[],
size_t,
const fmi2ValueReference[],
size_t,
const fmi2Real[],
fmi2Real[])
const fmi2ValueReference vUnknown_ref[],
size_t nUnknown,
const fmi2ValueReference vKnown_ref[],
size_t nKnown,
const fmi2Real dvKnown[],
fmi2Real dvUnknown[])
{
reinterpret_cast<Component*>(c)->logger.Log(
fmi2Error,
"cppfmu",
"FMI function not supported: fmi2GetDirectionalDerivative");
return fmi2Error;
const auto component = reinterpret_cast<Component*>(c);
try {
component->slave->GetDirectionalDerivative(
vUnknown_ref, nUnknown,
vKnown_ref, nKnown,
dvKnown, dvUnknown);
return fmi2OK;
} catch (const cppfmu::FatalError& e) {
component->logger.Log(fmi2Fatal, "", e.what());
return fmi2Fatal;
} catch (const std::exception& e) {
component->logger.Log(fmi2Error, "", e.what());
return fmi2Error;
}
}

fmi2Status fmi2SetRealInputDerivatives(
fmi2Component c,
const fmi2ValueReference[],
size_t,
const fmi2Integer[],
const fmi2Real[])
const fmi2ValueReference vr[],
size_t nvr,
const fmi2Integer order[],
const fmi2Real value[])
{
reinterpret_cast<Component*>(c)->logger.Log(
fmi2Error,
"cppfmu",
"FMI function not supported: fmi2SetRealInputDerivatives");
return fmi2Error;
const auto component = reinterpret_cast<Component*>(c);
try {
component->slave->SetRealInputDerivatives(vr, nvr, order, value);
return fmi2OK;
} catch (const cppfmu::FatalError& e) {
component->logger.Log(fmi2Fatal, "", e.what());
return fmi2Fatal;
} catch (const std::exception& e) {
component->logger.Log(fmi2Error, "", e.what());
return fmi2Error;
}
}

fmi2Status fmi2GetRealOutputDerivatives(
fmi2Component c,
const fmi2ValueReference [],
size_t,
const fmi2Integer[],
fmi2Real[])
const fmi2ValueReference vr[],
size_t nvr,
const fmi2Integer order[],
fmi2Real value[])
{
reinterpret_cast<Component*>(c)->logger.Log(
fmi2Error,
"cppfmu",
"FMI function not supported: fmiGetRealOutputDerivatives");
return fmi2Error;
const auto component = reinterpret_cast<Component*>(c);
try {
component->slave->GetRealOutputDerivatives(vr, nvr, order, value);
return fmi2OK;
} catch (const cppfmu::FatalError& e) {
Comment thread
joakimono marked this conversation as resolved.
component->logger.Log(fmi2Fatal, "", e.what());
return fmi2Fatal;
} catch (const std::exception& e) {
component->logger.Log(fmi2Error, "", e.what());
return fmi2Error;
}
}

fmi2Status fmi2DoStep(
Expand Down
86 changes: 86 additions & 0 deletions tests/cs_slave.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

#include <cstring>
#include <stdexcept>
#include <vector>


class TestSlave : public cppfmu::SlaveInstance
Expand All @@ -20,6 +21,8 @@ class TestSlave : public cppfmu::SlaveInstance
for (std::size_t i = 0; i < nvr; ++i) {
if (vr[i] == 0) {
value_ = value[i];
} else if (vr[i] == 2) {
seed_ = value[i];
} else {
throw std::logic_error("Invalid value reference");
}
Expand All @@ -34,12 +37,91 @@ class TestSlave : public cppfmu::SlaveInstance
for (std::size_t i = 0; i < nvr; ++i) {
if (vr[i] == 0) {
value[i] = value_;
} else if (vr[i] == 2) {
value[i] = seed_;
} else {
throw std::logic_error("Invalid value reference");
}
}
}

void SetBoolean(
const cppfmu::FMIValueReference vr[],
std::size_t nvr,
const cppfmu::FMIBoolean value[]) override
{
for (std::size_t i = 0; i < nvr; ++i) {
if (vr[i] == 1) {
derivativeSupported_ = (value[i] == cppfmu::FMITrue);
} else {
throw std::logic_error("Invalid value reference");
}
}
}

void GetBoolean(
const cppfmu::FMIValueReference vr[],
std::size_t nvr,
cppfmu::FMIBoolean value[]) const override
{
for (std::size_t i = 0; i < nvr; ++i) {
if (vr[i] == 1) {
value[i] = derivativeSupported_ ? cppfmu::FMITrue : cppfmu::FMIFalse;
} else {
throw std::logic_error("Invalid value reference");
}
}
}

void GetDirectionalDerivative(
const cppfmu::FMIValueReference vUnknown_ref[],
std::size_t nUnknown,
const cppfmu::FMIValueReference vKnown_ref[],
std::size_t nKnown,
const cppfmu::FMIReal dvKnown[],
cppfmu::FMIReal dvUnknown[]) const override
{
if (!derivativeSupported_) {
SlaveInstance::GetDirectionalDerivative(
vUnknown_ref, nUnknown,
vKnown_ref, nKnown,
dvKnown, dvUnknown);
}
for (std::size_t i = 0; i < nUnknown; ++i) {
dvUnknown[i] = 0.0;
for (std::size_t j = 0; j < nKnown; ++j) {
dvUnknown[i] += seed_ * dvKnown[j];
}
}
}

void SetRealInputDerivatives(
const cppfmu::FMIValueReference vr[],
std::size_t nvr,
const cppfmu::FMIInteger order[],
const cppfmu::FMIReal value[]) override
{
if (!derivativeSupported_) {
SlaveInstance::SetRealInputDerivatives(vr, nvr, order, value);
}
inputDerivatives_.assign(value, value + nvr);
inputOrders_.assign(order, order + nvr);
}

void GetRealOutputDerivatives(
const cppfmu::FMIValueReference vr[],
std::size_t nvr,
const cppfmu::FMIInteger order[],
cppfmu::FMIReal value[]) const override
{
if (!derivativeSupported_) {
SlaveInstance::GetRealOutputDerivatives(vr, nvr, order, value);
}
for (std::size_t i = 0; i < nvr; ++i) {
value[i] = seed_ * static_cast<cppfmu::FMIReal>(order[i]);
}
}

void GetFMUState(cppfmu::FMIFMUState* state) override
{
auto s = (*state == nullptr)
Expand Down Expand Up @@ -96,6 +178,10 @@ class TestSlave : public cppfmu::SlaveInstance
private:
cppfmu::Memory memory_;
cppfmu::FMIReal value_ = 0.0;
bool derivativeSupported_ = false;
cppfmu::FMIReal seed_ = 1.0;
std::vector<cppfmu::FMIReal> inputDerivatives_;
std::vector<cppfmu::FMIInteger> inputOrders_;
};


Expand Down
Loading